使用 print 与 println 时的顺序更改

Order changes when using print vs println

我一直在尝试在 clojure 中创建 monad,这样我就可以更彻底地将我的纯代码与我的不纯代码分开,而且我偶然发现了一些关于排序的问题。

将以下代码用于最小用例时,所需的输出是将 "Please enter your name: " 打印到屏幕,然后获取一行输入,然后将其打印回屏幕。下面的代码应该能够完成这个:

    ;; 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))))

然而,我遇到了一个问题,因为它会首先使用 (read-line) 轮询用户的输入,然后 之后 才会打印 "Please enter your name: ".

在更大的例子中,它仍然会以正确的顺序执行所有可见的 IO 操作,例如在这种情况下,它确实在打印出您输入的内容之前打印出 "Please enter your name: ",但它仍然请求先输入那个。

然而,最奇怪的部分是,当我在 io-print 中将 print 替换为 println 时,无论情况如何,它都会按预期进行所有排序。

为什么会发生这种情况?例如,print 是否有某种方式比 println 更懒惰?

需要在print后添加:

(flush)

println 将隐式地将输出刷新到屏幕,因此这就是为什么您会看到与 print.

不同的行为

详情请见https://clojuredocs.org/clojure.core/flush for more info, as also the source code