Program working in repl but nowhere else? - clojure

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

Related

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.

Support for ANSI escape sequence cursor moving

I'm making a simple ASCII animation, and I need the ability to place the cursor at an arbitrary point in the console screen.
While searching, I found this blog that shows this can be achieved by doing:
(print (str (char 27) "[2J")) ; clear screen
(print (str (char 27) "[;H")) ; move cursor to the top left corner of the screen
, which uses ANSI escape sequences.
The first line works as expected, but unfortunately, I haven't been able to find a console that allows for the second line to move the cursor.
After looking up how ANSI escape sequences work, I wrote up this function to ease it's use:
(defn move-cursor-to [x y]
(print (str (char 27) "[" y ";" x "H")))
But when I run (move-cursor-to 10 10), the output is wrong in every "console" I've tried:
IntelliJ/Cursive's REPL ignores it outright; printing nothing.
IntelliJ's Terminal prints the escape character as a ?, and literally prints the rest (?[10;10H)
The Window's 10 command prompt prints something similar to IntelliJ's Terminal, except the ? it prints is inside a box.
Am I doing something wrong? Is there a way to get this to work in the standard Windows 10 command prompt?
I wrote this to fill in the blanks in the meantime:
(defn move-cursor-to [x y]
(let [r #(apply str (repeat % %2))]
(print (str (r y \newline)
(r x \space)))))
but this is a poor solution. It requires clearing the screen prior to use, which for anything beyond a simple animation is unacceptable.
There is an easier way!
There is a much easier way to do this. Have a look at
the clojure-lanterna library.
This library will allow you to address an arbitrary location on a screen. It can
either use a terminal emulator or it can create a swing based window.
Another advantage of using this library is that it also incorporates support for
a virtual window or virtual screen, which can make your output appear to be
much smoother and reduces potential flicker.
The library also has support for ANSI colour codes and a few other nice
features.
Cursive only implements a limited subset of ANSI commands. In particular, most of the caret movement commands don't work. Feel free to file an issue for this, but fixing it is likely to be low priority since it's quite tricky to do in a REPL output pane.

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.

Clojure (load-file) gives an error

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?

I've rendered a shere to the Glut Window now how do I make it move around with the keyboard? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Cutting and pasting the cl-glut-examples code I rendered a sphere to the display. Now how do I move It on a x,y and z axis using the keyboard. Also is there an online resource to learn game programming in CL-OpenGL or how to make stuff like walls and dirt and houses and characters so I can create a 3D world and move characters around in it and come up with game logic for it.
Here is my code so far:
(defclass glut-teapot-window (glut:window)
()
(:default-initargs :width 948 :height 990 :title "glut-teapot.lisp"
:mode '(:single :rgb :depth)))
(defmethod glut:display-window :before ((window glut-teapot-window))
(gl:clear-color 0 0 0 0)
(gl:cull-face :back)
(gl:depth-func :less)
(gl:disable :dither)
(gl:shade-model :smooth)
(gl:light-model :light-model-local-viewer 1)
(gl:color-material :front :ambient-and-diffuse)
(gl:enable :light0 :lighting :cull-face :depth-test))
(defmethod glut:display ((window glut-teapot-window))
(gl:load-identity)
(gl:translate 0 0 -5)
(gl:rotate 100 1 1 0)
(gl:light :light0 :position '(6000 1000 15 0))
(gl:light :light0 :position '(2000 300 3000 0))
(gl:clear :color-buffer :depth-buffer)
(gl:color 1 1 1)
(gl:front-face :cw)
(glut:Solid-Sphere 1 10 10)
(gl:front-face :ccw)
(gl:flush))
(defmethod glut:reshape ((window glut-teapot-window) width height)
(gl:viewport 0 0 width height)
(gl:matrix-mode :projection)
(gl:load-identity)
(glu:perspective 50 (/ width height) 0.5 20)
(gl:matrix-mode :modelview)
(gl:load-identity))
(defmethod glut:keyboard ((window glut-teapot-window) key x y)
(declare (ignore x y))
(when (eql key #\Esc)
(glut:destroy-current-window)))
(defun glut-teapot ()
(glut:display-window (make-instance 'glut-teapot-window)))
(glut-teapot)
As I don't know your experience with opengl I'm going to write this answer for me a year back (when I knew nothing of opengl and was trying to learn using common lisp).
The cl-opengl library is a fairly tight wrapper around opengl, by this I mean most opengl functions have a direct equivalent in cl-opengl. This is good as it means that you will be able to take online tutorials for opengl using c & c++ and, with only a bit of mental strain, convert them to lisp.
The downside of it being a very tight wrapper around opengl is that opengl is not very lispy, by which I mean the style of good opengl code is very unlike good lisp code. This is definitely something that can be improved once you have got the hang of cl-opengl though.
Next, opengl is a library with two very different paradigms contained within it. There is old style
opengl (which uses gl-begin and gl-end) and new style opengl which is based on shaders is probably what you want if you want to do fancy effects in the future! The pain is that most of the good tutorials online are for old style opengl or mix the two in a way I found super confusing. Therefore I personally suggest the following tutorial for learning modern opengl:
http://www.arcsynthesis.org/gltut/
Once your through just the first 4 chapters you will understand enough opengl to be able to use the opengl wiki without too much pain. I say this as at first I found the opengl language wiki to be REALLY confusing as I had no context of how all the information should fit together.
Right now on to GLUT. GLUT is cool...But it gets very limiting very fast. I really suggest switching to SDL. Luckily some brilliant people have made SDL in lisp pretty nice to use in common-lisp and have called it lispbuilder-sdl.
http://code.google.com/p/lispbuilder/wiki/LispbuilderSDL
OK so how should you get going?:
Get quicklisp: I'm assuming you're using this already, but if not, GET IT NOW! It makes getting up-to-date packages for common lisp so much easier. http://www.quicklisp.org/beta/
Next, get lispbuilder (ql:quickload :lispbuilder-sdl)
Get familiar with opengl using the arcsynthesis tutorial. It really was the best way of getting the understanding I needed to be able to code modern opengl.
Write the examples from the arcsynthesis tutorial in lisp.
Make some functions and macros to make your opengl work nicer in lisp.
I'm only a few months ahead of you on this road and getting started was a real pain, but totally worth it. I'm sorry if you are skilled up on opengl and thus this answer was too basic for you! If so let me know and I will try to put a better answer up.
Below is the basic code to get up an opengl window and context in SDL, to handle events (your user input will go here) and to redraw the frame (nothing to draw yet but you will fill it with the stuff from the arc synthesis tutorial!).
Also I have added a helper function and macro. First is 'continuable' which will mean that if an error happens in the code inside it there will be an option in the error result to continue the program (Really handy so that you don’t have keep starting the demo again and again). Also there is update swank which will mean that even while the demo is running you can still use Slime (you are using slime right? If not GET IT!)
(defun init ()
(print 'initialise-stuff-here))
(defun draw ()
(gl:clear-color 0.0 0.0 0.0 0.0)
(gl:clear-depth 1.0)
(gl:clear :color-buffer-bit :depth-buffer-bit)
(gl:flush)
(sdl:update-display))
(defun reshape (width height)
(print width )
(print height)
(gl:viewport 0 0 width height))
(defmacro continuable (&body body)
"Helper macro since we use continue restarts a lot
<remember to hit C in slime or pick the restart so errors don't kill the app>"
`(restart-case (progn ,#body)
(continue () :report "Continue")))
(defun update-swank ()
(let ((connection (or swank::*emacs-connection*
(swank::default-connection))))
(when connection
(swank::handle-requests connection t))))
(defun run-demo ()
(sdl:with-init ()
(sdl:window
640 480 :opengl t
:resizable t
:opengl-attributes '((:sdl-gl-doublebuffer 1)
(:sdl-gl-alpha-size 0)
(:sdl-gl-depth-size 16)
(:sdl-gl-stencil-size 8)
(:sdl-gl-red-size 8)
(:sdl-gl-green-size 8)
(:sdl-gl-blue-size 8)))
(init)
(reshape 640 480)
(setf cl-opengl-bindings:*gl-get-proc-address* #'sdl-cffi::sdl-gl-get-proc-address)
(sdl:with-events ()
(:quit-event () t)
(:VIDEO-RESIZE-EVENT (:w width :h height)
(reshape width height))
(:idle ()
(continuable (update-swank))
(continuable (draw))))))
Ok, that’s it, have fun!