Clojure (load-file) gives an error - clojure

Whenever I try to use (load-file) on my home computer (OSX) it throws the following error:
IllegalArgumentException Parameter declaration comp should be a vector clojure.core/assert-valid-fdecl (core.clj:6732)
When I load the same file on my Windows box at work it works. What is the difference between (load-file "C:\clojure\pc-3.clj") and (load-file "/Users/myname/clojure/pc-3.clj") that is throwing the error. Other than the path structure with the slashes is different but I don't understand why this is not working on my both systems.
BTW: Other than OS both systems are running JRE 1.7_025 with clojure-1.5.1.
UPDATE:
I was asked for a stack trace and I'm not sure how to do this just started working with Clojure. But emacs nrepl-error buffer listed this out for me:
java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.String
RT.java:318 clojure.lang.RT$3.invoke
NO_SOURCE_FILE:1 user/eval278
Compiler.java:6619 clojure.lang.Compiler.eval
Compiler.java:6582 clojure.lang.Compiler.eval
core.clj:2852 clojure.core/eval
main.clj:259 clojure.main/repl[fn]
main.clj:259 clojure.main/repl[fn]
main.clj:277 clojure.main/repl[fn]
main.clj:277 clojure.main/repl
RestFn.java:1096 clojure.lang.RestFn.invoke
interruptible_eval.clj:56 clojure.tools.nrepl.middleware.interruptible-eval/evaluate[fn]
AFn.java:159 clojure.lang.AFn.applyToHelper
AFn.java:151 clojure.lang.AFn.applyTo
core.clj:617 clojure.core/apply
core.clj:1788 clojure.core/with-bindings*
RestFn.java:425 clojure.lang.RestFn.invoke
interruptible_eval.clj:41 clojure.tools.nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj:171 clojure.tools.nrepl.middleware.interruptible-eval/interruptible-eval[fn]
core.clj:2330 clojure.core/comp[fn]
interruptible_eval.clj:138 clojure.tools.nrepl.middleware.interruptible-eval/run-next[fn]
AFn.java:24 clojure.lang.AFn.run
ThreadPoolExecutor.java:1145 java.util.concurrent.ThreadPoolExecutor.runWorker
ThreadPoolExecutor.java:615 java.util.concurrent.ThreadPoolExecutor$Worker.run
Thread.java:724 java.lang.Thread.run
UPDATE: Found out what the problem was today. I was having the exact same problem with my Windows box turns out that the original answer was correct but my assumption that it had to do with (load-file) was incorrect. The file I was loading had a function that was not using a vector [] as part of the function itself. Clojure was doing the correct thing (but I totally forgot about this) when loading the file checking the syntax to make sure that everything was complete in the file. My function wasn't so it wouldn't load the file. I forget that LISPs do this and that it's a feature not a bug (reason why I like LISPs).
I'm new to clojure but not to LISPs and I should have realized this. The file is my study file. All the examples I retype from the REPL why studying and the reload the file with the newest to make sure I typed it in correct. It appears that when I added the newest function to file I retyped it incorrect and didn't reload the file to check it. When I went away and closed down the REPL and then came back after dinner and tried to reload the file it wouldn't load.
So sorry for being a waste of time. But thanks for the help, and quickly too. The original answer was correct I just forgot to recheck all the functions in the file.

That error indicates that the compiler was processing something like
(defn function-name comp (do-stuff ...))
or perhaps
(defn [arg1] comp (do-stuff ...))
instead of
(defn function-name [comp] (do-stuff ...))
load-file takes a string not a vector (load-file "path/to/file.clj)
Could it be that the code is not the same on the two systems?
Could there be a difference in path interpretation / vs \ causing something else to get loaded?

Related

Program working in repl but nowhere else?

I suspect this may be somewhat related to java-interop since I call a lot of java functionality in my code.
When I run the following in my REPL (via emacs) it works exactly as it should
(def height 100)
(def image (BufferedImage. width height BufferedImage/TYPE_INT_ARGB))
(def graphics (.createGraphics image))
(.setColor graphics Color/black)
(for [x (range 0 width 10)]
(.drawLine graphics x 0 x height ))
(for [y (range 0 height 10)]
(.drawLine graphics 0 y width y))
(ImageIO/write image "png" (io/file "output.png"))
An image of a grid is properly generated.
However if I do C-c C-k, it generates a blank image.
Now, when I stick it in a function and I run it via lein run I get a warning I don't understand:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by clojure.lang.InjectedInvoker/1832669781 (file:/home/n/.m2/repository/org/clojure/clojure/1.10.0/clojure-1.10.0.jar) to method sun.java2d.SunGraphics2D.setColor(java.awt.Color)
WARNING: Please consider reporting this to the maintainers of clojure.lang.InjectedInvoker/1832669781
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
I know very little about clojure and even less about java, but I am running openjdk 10.
I believe my code is written correctly (albeit poorly), is this an issue with my code or is it clojure?
I suspect the problem you have is that “for” does not do what you think it does. It generates a lazy sequence. At the REPL the printer will generally evaluate these, but standalone code will not.
Try replacing the for with doseq. This will eagerly execute your side effects and should improve matters.
The illegal access warnings are a red herring. Since the Java module system came in there are certain patterns of interop which generate them. Details of how to resolve the warnings are given in the Clojure FAQ at https://clojure.org/guides/faq#illegal_access

How can I get readline/rlwrap-like functionality when using clojure.main/repl?

How can I get readline-like (or rlwrap-like) functionality from my REPL when I use the repl function from clojure.main?
The background to this is that I'm utilizing and customizing the break function from The Joy of Clojure, First Edition. I'm using it from inside the lein repl REPL. When my "breakpoint" kicks in, the readline-like functionality of Leiningen's REPL is gone, which is kind of inconvenient. My muscle memory makes me hit ↑ followed quickly by Enter. Before I can stop myself, I've got this in my terminal:
debug=> ^[[A
CompilerException java.lang.RuntimeException: Unable to resolve symbol: in this context, compiling:(/tmp/form-init13211381000659590518.clj:1:1)
And now my REPL is stuck and I have to kill the terminal or the process to get out. I'd like very much if I could either get readline working in this second-level REPL or at least prevent this common issue from derailing my debug sessions.
You should use rebel readline, a new repl for clojure developed by bhauman the same guy who brought is figwheel.
https://github.com/bhauman/rebel-readline
It has rlwrap features, syntax highlighting and multi line code editing all in the terminal.
I'm not sure the rlwrap utility would help there, because the inner REPL is held by the outer one. So the input is being controlled by Java code, not the rlwrap tool.
You are causing an exception since you input a wrong value. I remember, the clojure.main/repl function might take an additional argument to handle exceptions. Probably, you could handle it somehow and just print a string "wrong input value" instead. Take a look at the documentation for REPL.
Also, you may implement your own REPL for debugging. Long ago, I used to write some kind of it, here what I've got:
(defn repl []
(let [input (read)]
(if (= input 'q)
nil
(do
(try
(let [result (eval input)]
(println result))
(catch Exception e
(println e)))
(recur)))))
That function just prompts for a proper Clojure expression in an endless loop, evaluates it and prints the result. In case of a wrong input, it prints the error and carries on. To leave the REPL, input q.
Example:
(repl)
(+ 1 2) ;; 2
fsdf8 9_fsd ;; prints a stack trace
q ;; returns nil and exit
Try Emacs with Cider as your repl. When you (break) you'll be bumped out of the Cider repl and into the Emacs Minibuffer, where your standard emacs editing shortcuts (upon which readline is modeled) continue to apply.

Clojure eval causes garbage collector to hang

I encounter this problem when running a genetic programming algorithm which uses eval.
To illustrate the problem, I narrowed it down to the following code fragment:
(loop []
(do
(eval (list '+ (rand) (rand)))
(recur)))
When I run the code the garbage collector unloads all the created $eval_n classes once from metaspace but on the second garbage collector invocation it hangs.
I use jdk1.8.0_102 with the follwing JVM options:
-XX:MetaspaceSize=200m
-XX:MaxMetaspaceSize=200m
After a while I get the following error:
CompilerException java.lang.OutOfMemoryError: Metaspace, compiling:(form-init2581690491924993906.clj:1:1)
EDIT:
I added a screenshot of visualVM to show the behaviour, when the JVM hangs, the graph is not updated anymore, and it keeps using a full CPU core.
I also tried it using java 7 (without any JMV options), and I encounter the same problem with PermGen.
Any ideas how to avoid this problem?
EDIT:
The problem only occurs when I run it from a leinigen-REPL with eclipse-counterclockwise. If I run the code from a basic command line REPL the problem does not occur!
I noticed steadily increasing memory consumption with the above example. Adding a System/gc
(loop [] (do (eval (list '+ (rand) (rand))) (System/gc)) (recur))
doubled CPU consumption but kept memory usage at what looked like a long term steady state.
I concluded this problem is not directly related to clojure eval or the JVM. It only occurs in combination with eclipse-counterclockwise and/or a leiningen-REPL.

Getting a dump of all the user-created functions defined in a repl session in clojure

Is there a way to get a dump of all the source code I have entered into a repl session. I have created a bunch of functions using (defn ...) but did it 'on the fly' without entering them in a text file (IDE) first.
Is there a convenience way to get the source back out of the repl session?
I note that:
(dir user)
will give me a printed list of type:
user.proxy$java.lang.Object
so I can't appear to get that printed list into a Seq for mapping a function like 'source' over. And even if I could then:
(source my-defined-fn)
returns "source not found"...even though I personally entered it in to the repl session.
Any way of doing this? Thanks.
Sorry, but I suspect the answer is no :-/
The best you get is scrolling up in the repl buffer to where you defined it. The source function works by looking in the var's metadata for the file and line number where the functions code is (or was last time it was evaluated), opening the file, and printing the lines. It looks like this:
...
(when-let [filepath (:file (meta v))]
(when-let [strm (.getResourceAsStream (RT/baseLoader) filepath)]
(with-open [rdr (LineNumberReader. (InputStreamReader. strm))]
(dotimes [_ (dec (:line (meta v)))] (.readLine rdr))
...
Not including the full source in the metadata was done on purpose to save memory in the normal case, though it does make it less convenient here.

How to exit the REPL

I'm trying to exit the REPL.
I use (. System exit 0) or (System/exit 0), but that causes an error:
Exception in thread "Thread-3" java.lang.RuntimeException: java.lang.IndexOutOfBoundsException
Is there another way to exit the REPL? How I can resolve this error?
You can send the 'end-of-file' character.
You can just press ctrl-d (*nix) or ctrl-z (Windows) to exit the REPL.
My answer is now 10 years old and was given a context of less understanding (although I think I shared the same confusion as the original asker so it kind of works).
(System/exit 0) does indeed exit the whole JVM - that might be what you want "to exit the REPL" but not necessarily. Clojure and it's REPL are designed to run in a multi-threaded environment and you can even have multiple REPLs connected to the same process. Obviously exiting the JVM is not what you want if you want to exit a REPL in an otherwise continuing process.
Original answer below:
It looks like you have a different problem in your code.
The way to exit the repl is:(System/exit 0)
The alternative syntax (. System exit 0) also works.
You can test this from a clean repl started with:
java -cp clojure.jar clojure.main -r
The exception you get would seem to indicate an error in some indexed lookup before your code gets to the intended exit point, apparently on a different thread.
The problem with (System/exit 0) is that it kills the whole JVM. The real question is how to programmatically exit just the current repl, and return to whatever function launched that repl.
Here is a convenient hack:
(clojure.main/repl
; Exit the repl whenever the user enters "exit" at the prompt.
:read (fn [request-prompt request-exit]
(let [form (clojure.main/repl-read request-prompt request-exit)]
(if (= 'exit form) request-exit form))))
clojure.main/repl repeatedly calls a a reader, by default repl-read, to get one form at a time. One of the arguments to the reader is a special sentinel object that the reader is supposed to return when there are no more forms to be read. The default reader, repl-read, returns the sentinel value only on EOF. At the repl-read prompt, you do not have access to the sentinel object, so you cannot return it to tell the evaluator that you have finished entering forms. By installing your own reader, you can check for a particular form -- e.g., the symbol exit -- and return the sentinel object whenever this form is read, thus indicating to the evaluator that you are ready to exit the repl, without actually killing the entire VM.
i just wanted to exit my REPL and landed here.
This seems to be a question that comes to everyones mind when starting to do first steps in the Clojure REPL. And of course I did not read the start-up message. The answer for my Clojure 1.7.0 is (exit) or (quit) or Control-d as stated in other replies.
nREPL server started on port 49276 on host 127.0.0.1 - nrepl://127.0.0.1:49276
REPL-y 0.3.7, nREPL 0.2.10
Clojure 1.7.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_72-b15
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=> (exit)
Bye for now!
You may use the following key combination to exit Cider REPL in emacs: C-c C-q
If you install "lein" then it's exit or quit like this:
$ lein repl
...
user=>exit
Bye for now!
On Mac, use CTRL + C twice, see:
to exit the repl:
If you're running the repl from the command line then (as Sean mentions) ctrl-d
if you're running it from slime then Alt-x slime-quit-lisp should do it.
if you're running it from eclipse then i'm not sure there is a clean way to exit use the little red button.
today I have the answer, this is what I need
(import ('java.lang.management ManagementFactory)
(use 'clojure.contrib.shell)
(defn process-pid [] (let [m-name (.getName (ManagementFactory/getRuntimeMXBean))] (first (.split m-name "#"))))
(defn exit (sh "kill" (process-pid))
In Windows (tested on Windows 7 x64), using the standard command shell (cmd.exe), the ctrl-Z (followed by the enter key) character appears to be the end-of-file indicator, it dropped me out of the REPL back to the command prompt. I suspect that this will also work equivalently in Windows PowerShell, would someone who is familiar with it please test and confirm...
Note also that this is for the stock Clojure REPL - if you are running the Datomic shell (which appears to be an instance of a Java Beanshell), enter "quit();"...
HTH.
On Clojure 1.10.2 installed on Linux
(. System exit 0)