Clojure: * out * vs System / out

I'm trying to translate a small console program that I wrote in Java in Clojure, but I find it a little difficult to figure out the difference between Clojure standard *out* var and an object in System/out , I got the impression that this is the same thing, but when during my testing they seem different.

In my program, I invite the user to enter a number, and I want the prompt and input text to be on the same line. In Java, I printed a prompt using System.out.print() , and then the scanner read the input.

Next was my first attempt at something similar in Clojure. Although the print function seems to work before the read-line , it immediately blocks the input and prints everything after a messy mess:

 (defn inp1 [] (print "Enter your input: ") (let [in (read-line)] (println "Your input is: " in))) 

Next was my next attempt using *out* . He is experiencing the same problem as above:

 (defn inp2 [] (.print *out* "Enter input: ") (let [i (read-line)] (println "You entered: " i))) 

In my third attempt, I finally started working using System/out directly:

 (defn inp3 [] (let [o System/out] (.print o "Enter input: ") (let [i (read-line)] (println "You entered: " i)))) 

I'm glad I finally got him a job, but I'm deeply confused about why the third one works the way I want, when the first two don't do it. Why the first two blocks at once? Can anyone shed some light on this?

+7
clojure
source share
1 answer

Per Docs :

*out* - A java.io.Writer object representing standard output for print operations. By default, System / out wrapped in OutputStreamWriter

... so you have a wrap layer. Look at the docs for this layer (highlighted by me):

Each call to the write () method forces the encoder to be converted to the specified character (s). The resulting bytes are accumulated in the buffer before being written to the base output stream. The size of this buffer can be specified, but by default it is large enough for most purposes. Note that characters passed to write () methods are not buffered.

... added emphasis. Since the buffers are OutputStreamWriter , you need to call .flush to force the text to be written.

+8
source share

All Articles