Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure - Side Effects Happening Out Of Order

Tags:

clojure

While dabbling in Clojure I've written a very basic program to echo whatever the user types into it. However, it doesn't run in a way that I'm perceiving to be natural. Here's the code:

(defn goo []
  (print "echo> ")
  (def resp (read-line))
  (print resp)
)

I would expect the code to run like this (for me typing in foo as the input to read-line):

user=> (goo)
echo> foo
foonil

But instead, the echo and read-line is switched:

user=> (goo)
foo
echo> foonil

Why does this happen? Is there a subtlety I'm missing?

EDIT: From Joe's answer, the updated correct solution is:

(defn goo []
  (print "echo> ")
  (flush)
  (def resp (read-line))
  (print resp)
  (flush)
)

Also, the flushes aren't necessary if you use println instead of print.

like image 862
Chris Bunch Avatar asked Dec 23 '08 03:12

Chris Bunch


2 Answers

I know nothing of clojure but this sounds like a case of buffers not getting flushed. Figure out how to flush standard out after the print. The println function probably flushes at the end of each line. Try:

(defn goo []
  (print "echo> ")
  (flush )
  (def resp (read-line))
  (print resp)
)
like image 98
jmucchiello Avatar answered Nov 17 '22 03:11

jmucchiello


Also, please don't use "def" unless you really, really want to define a global variable. Use "let" instead:

(defn goo []
  (print "echo> ")
  (flush)
  (let [resp (read-line)]
    (print resp)
    (flush)))

or, shorter

(defn goo []
  (print "echo> ")
  (flush)
  (print (read-line))
  (flush))
like image 43
Mark Probst Avatar answered Nov 17 '22 02:11

Mark Probst