使用print vs println时订单更改

时间:2017-09-08 21:02:29

标签: clojure monads purely-functional

我一直在尝试在clojure中创建monad,这样我就可以将我的纯代码与我不纯的代码分开了,而且我偶然发现了一些订购的东西。

当使用以下代码作为最小用例时,所需的输出是用于打印"请输入您的姓名:"到屏幕然后取一行输入,然后打印回屏幕。下面的代码是应该能够实现的:

    ;; 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)轮询来自用户的输入,之后只有 然后会打印"请输入您的姓名:"。

在较大的示例中,它仍将以正确的顺序执行所有可见的IO操作,例如,在这种情况下,它会打印出来"请输入您的姓名:"在打印出你输入的内容之前,它仍然会先请求输入。

然而,最奇怪的部分是我在print中用println替换io-print的瞬间,无论情况如何,它都按照意图执行所有排序。

为什么会发生这种情况?例如,print是否存在println懒惰的某种方式?

1 个答案:

答案 0 :(得分:3)

您需要在print之后添加以下内容:

(flush)

println将隐式刷新输出到屏幕,这就是为什么您看到的行为与print不同。

有关详细信息,请参阅https://clojuredocs.org/clojure.core/flush,所有详细信息均为also the source code