Clojure, Quil: Printing in draw function - clojure

I am a Clojure and Quil beginner.
As part of development, I would like to print information to the REPL in the draw function.
However, the following implementation doesn't work. There are no error generated, but it doesn't print anything either.
Why doesn't it work, and how can I print to the REPL from Quil draw functions?
Thank you in advance.
(ns quil-learning.core
(:use quil.core))
(defn setup []
(smooth)
(frame-rate 60)
(background 255))
(def saved-out *out*)
(defn draw []
(println "test 1") ; doesn't work
(let [*out* saved-out] (println "test 2")) ; doesn't work either
(stroke 0)
(stroke-weight 2)
(ellipse (mouse-x) (mouse-y) 2 2))
(defsketch example
:title "print test"
:setup setup
:draw draw)

nrepl is writing your output to the wrong buffer, this was supposed to be fixed for most contexts in nrepl 0.1.4 http://grokbase.com/t/gg/clojure/129jwz1yh9/ann-nrepl-el-0-1-4-released. I suggest using emacs24+ and using it's built in packaging system to keep nrepl up to date. see the Emacs starter kit for details. Or you can take a look at my fork of it which adds nrepl and clojure-mode to the default package list
check the terminal from which you started emacs, sometimes it lands there.

Related

Sending message to Clojure application from terminal

How does one send a message to a running clojure application? For example, if I have a particular variable or flag I want to set from the terminal when the uberjar is running - is this possible?
One way is to read a file in the application that you can change, but that sounds clunky.
Thanks in advance!
One way to do this is by having your application host a nREPL (network REPL). You can then connect to your running app's nREPL and mess around.
For example, your app may look like this:
(ns sandbox.main
(:require [clojure.tools.nrepl.server :as serv]))
(def value (atom "Hey!"))
(defn -main []
(serv/start-server :port 7888)
(while true
(Thread/sleep 1000)
(prn #value)))
While that's running you can lein repl :connect localhost:7888 from elsewhere and change that value atom:
user=> (in-ns 'sandbox.main)
#object[clojure.lang.Namespace 0x12b094cf "sandbox.main"]
sandbox.main=> (reset! value "Bye!")
"Bye!"
By this time the console output of your app should look like this:
$ lein run
"Hey!"
"Hey!"
<...truncated...>
"Bye!"
"Bye!"
There are many options for interprocess communication on the JVM, but this approach is unique to Clojure.

How to reload (stop and start) an http-kit "mount state" on a -main function

With the mount library, how do I reload (stop and start) an http-kit "mount state" on a -main function?
My current code is this:
(defstate server-config :start {:port 7890 :join? false})
(defn start-server [server-config]
(when-let [server (run-server myserv-ring-handler server-config)]
(println "Server has started!")
server))
(defstate myserv-server :start (start-server server-config)
:stop (myserv-server :timeout 100))
(defn system-port [args]
(Integer/parseInt
(or (System/getenv "PORT")
(first args)
"7890")))
(defn -main [& args]
(mount/start-with-states
{#'myserv/server-config
{:start #(array-map :port (system-port args)
:join? false)}}))
So when I "lein run" everything works, but whenever I change a file, and the http-kit server is stopped, the command stops. For the moment I'm doing "while true; do lein run; done" to work, so I've thought about adding an infinite loop to the -main function, but it doesn't feel like this is the right way.
How should I do this?
I would suggest adding some metadata to your http server defstate.
From the mount readme:
In case nothing needs to be done to a running state on reload /
recompile / redef, set :on-reload to :noop:.
So try something like this:
(defstate ^{:on-reload :noop}
myserv-server
:start (start-server server-config)
:stop (my-stop-func myserv-server))
This means that when you change a file, the affected code will be reloaded, but the http server will continue to run.
I hope that I've correctly understood your question and that this is what you wanted.
Could I also suggest that if you want to get up and running quickly, then there are various templated web app projects for Leiningen. For example, the Luminus project. You can pass an +http-kit parameter to the lein new luminus myapp command and that will wire up an app correctly for you. You can then go and read the generated code and learn how it all fits together.
So I had a couple of separate problems:
I didn't understand that now I didn't need to use lein run, but instead I could just do lein repl and start the server from there. The restarting problem is avoided that way.
The other one was that I was misusing start-with-states instead of a config state.
You can see a discussion about this with the author of the library here.

How to set a timeout on a Hystrix command in Clojure?

I'm learning about Hystrix and Clojure and don't understand how to (properly) set a timeout on a Hystrix command in Clojure.
I searched StackOverflow and the web more generally. I looked at Hystrix's Clojure wrapper source code (https://github.com/Netflix/Hystrix/blob/master/hystrix-contrib/hystrix-clj/src/main/clojure/com/netflix/hystrix/core.clj). There is a init-fn function parameter that looked promising, but the comments seem to suggest that this won't be a sustainable solution. But would this be a simple start?
I have a ridiculously simple Hystrix command running in Clojure and would appreciate help in extending this to set, say, a 200ms timeout:
(ns hystrix-timeout.core
(:require [clojure.string :as str])
(:require [com.netflix.hystrix.core :as hystrix])
(:gen-class))
(defn my-primary [a]
(if (= a true) (throw (Exception. "Primary failed")) (str "primary: " a)))
(defn my-fallback [a]
(str "fallback: " a))
(hystrix/defcommand my-command
{:hystrix/fallback-fn my-fallback}
[a]
(my-primary a))
(defn -main
"Executes a simple Hystrix command. Will use a timeout when I know how to do this in Clojure."
[& args]
(println (my-command false))
(println (my-command true))
(System/exit 0) ; Exit explicitly as Hystrix threads are still running.
)
I've put my lein project up at https://github.com/oliverbaier/learning/tree/master/hystrix-timeout in case this makes answering easier.
Thanks a lot,
Oliver
The simplest route is to just use System properties. You can set either a global default:
(System/setProperty "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds" "200")
or a command specific value:
(System/setProperty "hystrix.command.my-command.execution.isolation.thread.timeoutInMilliseconds" "200")
You can perform this in your -main method. If you are running a real web-app sans -main, you can add a ring init in project.clj :ring {:handler your-handler :init your-config-method} your-config-method will be invoked on startup.

Why can't I instantiate a defrecord-generated class after use'ing its namespace?

I'm relatively new to Clojure and going through the Clojure chapter in Seven Languages in Seven Weeks, and I can't figure out why this code from the book isn't working for me. I'm using Leiningen and Clojure version 1.5.1. As far as I can tell after careful checking, I typed the code exactly as it reads in the book.
Here is the code:
(ns seven-languages.compass)
(defprotocol Compass
(direction [c])
(left [c])
(right [c]))
(def directions [:north :east :south :west])
(defn turn [base amount]
(rem (+ base amount) (count directions)))
(defrecord SimpleCompass [bearing]
Compass
(direction [_] (directions bearing))
(left [_] (SimpleCompass. (turn bearing 3)))
(right [_] (SimpleCompass. (turn bearing 1)))
Object
(toString [this] (str "[" (direction this) "]")))
I'm running "lein repl" from within the directory ~/clojure/seven-languages (created by running "lein new seven-languages" in ~/clojure). Relative to this directory, my .clj files are in src/seven_languages. So far I've been able to successfully import and use them from the repl by typing (use 'seven-languages.filenamehere).
So, after saving the code I listed above as src/seven_languages/compass.clj, I run this from the REPL:
user=> (use 'seven-languages.compass)
nil
But then when I try to define an "instance" of the SimpleCompass, typing it exactly like in the book, this happens:
user=> (def c (SimpleCompass. 0))
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: SimpleCompass, compiling:(NO_SOURCE_PATH:1:8)
I also tried loading the file using (load-file "src/seven_languages/compass.clj"), but got the same results. Since the actual loading seemed to work as expected, I wonder if there has been some change in how defprotocol or defrecord works in versions of Clojure subsequent to when Seven Languages in Seven Weeks was written. In the introduction to the Clojure chapter, the author writes, "I’m using a prerelease version of Clojure 1.2, and it should be fully ready by the time this book is in your hands."
Can anyone tell why this code isn't working properly? If it's a version issue, how would you update this code for Clojure 1.5.1?
EDIT: Aha! I figured it out after finding this:
Clojure - deftype ignored - unable to resolve classname on tests
It's a namespace issue. I'm guessing this is a change since version 1.2 when 7LI7W was written. For whatever reason, while functions in imported files are "automatically handled" so that you can just use them directly, types are not automatically handled. You have to include the full path to the type, and make sure you use the actual path with underscores, not hyphens. I got my code to work by substituting SimpleCompass with the full path, seven_languages.compass.SimpleCompass:
user=> (def c (seven_languages.compass.SimpleCompass. 0))
#'user/c
user=> c
#seven_languages.compass.SimpleCompass{:bearing 0}
user=> (left c)
#seven_languages.compass.SimpleCompass{:bearing 3}
user=> (right c)
#seven_languages.compass.SimpleCompass{:bearing 1}
Apart from always fully qualifying the class name, you can import it and use the short name afterwards:
(import seven_languages.compass.SimpleCompass)
;; (SimpleCompass. 0) etc. will work now
Also, it's worth pointing out that defrecord creates to factory functions for you, one positional and one taking a map:
(defrecord Foo [x])
(->Foo 1)
;= #user.Foo{:x 1}
(map->Foo {:x 1})
;= #user.Foo{:x 1}
These are just regular functions and so will have been pulled in by your use call.
Relatedly, deftype, as of Clojure 1.5.1, creates the positional factory only.

How do I live code in Clojure using Emacs / nrepl / Quil?

I have a fairly standard Quil file that I am editing with Emacs and nrepl.
(defn setup []
(qc/smooth)
(qc/frame-rate 24)
(qc/background 200))
(defn draw []
(draw-world))
(qc/defsketch run
:title "Circles!"
:setup setup
:draw draw
:size [800 600]
:renderer :opengl)
To start with, I use C-c C-l to load the file; this creates a sketch window. I then edit my draw-world function to, say, draw in a different color. My question is:
How do I update the current Quil window with this new function?
*C-x C-e doesn't seem to work.
Try C-M-x (this evals the current top-level form) in the function you want to change or C-c C-k (this evals the current buffer) in the source buffer. Btw, C-x C-e should be working too (it certainly works for me, but I rarely use it). Maybe you're not using nrepl.el's latest version?
I just set up a sample project to handle my workflow for live-coding in Quil. I copied some basics from several places, such as the Quil wiki and forums.
If you look at the basic core.clj file of the project, you'll see it requires separate "draw" and "setup" namespaces:
(ns basic-metronome.core
(:use [basic-metronome.setup :only [HEIGHT WIDTH]])
(:require [basic-metronome.draw :as dynamic-draw]
[basic-metronome.setup :as dynamic-setup]
[quil.core :as qc]))
(defn run-sketch []
(qc/defsketch the-sketch
:title "Hello Metronome"
:setup dynamic-setup/setup
:draw dynamic-draw/draw
:size [WIDTH HEIGHT]))
From:
https://github.com/mudphone/basic_quil_metronome/blob/master/src/basic_metronome/core.clj
In this way, I can re-evaluate C-c C-k the draw.clj file without having to re-evaluate the top-level core namespace (which can cause problems, such as the one you describe where you're seeing a new window).