Order changes when using print vs println

162 views Asked by At

I've been experimenting with creating monads in clojure so I can separate my pure code from my impure code more thouroghly, and I've stumbled upon something strage with ordering.

When using the following code for a minimum use-case, the desired output is for it to print "Please enter your name: " to the screen and then take a single line of input, which is then printed back out to the screen. The code below is what should be able to acccomplish this:

    ;; IO Monad definitions

    (defn io-bind
      [mv mf]
      (fn []
        (let [val (mv)
              f (mf val)]
          (f))))

    ;; Monadic functions

    (defn io-print
      [msg]
      (fn []
        (print msg)))

    (defn io-read-line
      [_]
      (fn []
        (read-line)))

    ;; Entry point

    (defn -main
      "I don't do a whole lot ... yet."
      [& args]
      ((-> (io-print "Please enter your name: ")
           (io-bind io-read-line)
           (io-bind io-print))))

I've experienced a hitch with this however, in that it will first poll for input from the user using (read-line) and only afterwards will it then print "Please enter your name: ".

In larger examples, it will still perform all of the visible IO actions in the proper order, for example in this case it does print out "Please enter your name: " before it prints out what you inputted, yet it still requests that input first.

The strangest part however is that the instant I replace print with println in io-print it does all of the ordering as intented, regardless of circumstance.

Why might this be occuring? Is there some way that print is lazy that println is not, for example?

1

There are 1 answers

0
Alan Thompson On BEST ANSWER

You need to add the following after the print:

(flush)

println will implicitly flush the output to the screen, so that is why you are seeing different behavior than with print.

Please see https://clojuredocs.org/clojure.core/flush for more info, as also the source code for all the details.