Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
第二个println语句会发生什么?(Clojure回复)_Clojure - Fatal编程技术网

第二个println语句会发生什么?(Clojure回复)

第二个println语句会发生什么?(Clojure回复),clojure,Clojure,当我在clojure REPL中调用这个小函数时,它只打印第一个hello world,而不是hello mars。为什么呢?它不是懒惰的(据我所知),否则异常不会被命中,另外,它告诉我println会导致刷新 (defn foo

当我在clojure REPL中调用这个小函数时,它只打印第一个hello world,而不是hello mars。为什么呢?它不是懒惰的(据我所知),否则异常不会被命中,另外,它告诉我println会导致刷新

(defn foo                                                                                                                                                           
     "I don't do a whole lot."                                                                                                                                         
     [x]                                                                                                                                                               
     (println x "Hello, World!")                                                                                                                                       
     (map (fn [x] (let [_ (println "Hello, Mars")                                                                                                                      
                        __ (throw (Exception. "talking to many planets"))]                                                                                             
                    { :aliens? false }                                                                                                                                 
                   )) [1 2 3])                                                                                                                                        
)    
输出:

(无)无你好,世界

与许多行星交谈测试异常。repl/foo/fn--6580 (表格-init13300486174634970.clj:5)


好的,我有个主意。Map返回一个惰性seq。repl在试图实现它的映射上调用println(或类似),调用.toString()(或类似)。在内部,当在print/ln中调用print/ln时,它会保存输出,直到它自己完成为止,因此异常将意味着收集的其他位(print内的print)调用不会刷新

首先,
map
实际上是惰性的,因此
foo
返回一个
LazySeq
,当REPL打印它时,它会被强制执行。现在,当我使用bare Clojure(
java-jar Clojure.jar
)运行您的示例时,我得到以下输出:

user=> (foo nil)
nil Hello, World!
(Hello, Mars
Exception talking to many planets  user/foo/fn--1 (NO_SOURCE_FILE:5)
user=> 
我在Clojure 1.4.0和1.5.1中得到了相同的结果

现在,如果我通过
leinrepl
运行,就会得到您描述的输出。因此,nrepl链中的某些内容似乎正在影响打印方式。这是有意义的,因为nrepl设计用于通过网络与客户端通信。然而,在处理这个案例的过程中,似乎有一个小错误。或者在打印值时,它会将换行符上的flush重新绑定为false?对不起,我还没有深入到代码中给出更明确的答案


顺便说一句,如果将函数调用包装在
println
中,即
(println(foo nil))
,则会得到上面所示的预期输出。

我刚刚尝试了相同的代码,我看到了
你好,Mars异常
之前打印code>,如果您没有看到这种奇怪的行为,我会预测到这一点<代码>零你好,世界!(你好,Mars Exception talking to many planets user/foo/fn--6(NO_SOURCE_FILE:19)。Clojure版本是1.5.1。你在使用哪个jvm?对我来说:java版本“1.7.0_25”OpenJDK运行时环境(IcedTea 2.3.12)(7u25-2.3.12-4ubuntu3)OpenJDK 64位服务器虚拟机(构建23.7-b01,混合模式)我已经在lubuntu上试用了
版本“1.7.0_25”OpenJDK运行时环境(IcedTea 2.3.10)(7u25-2.3.20-lubuntu0.13.04.2)OpendJDK Zero虚拟机(构建22.0-b10,混合模式)
和Windows 7中的
java版本“1.7.0_21”java(TM)SE运行时环境(构建1.7.0_21-b11)热点java(TM)客户机虚拟机(构建23.21-b01,混合模式)
,我在这两个方面都得到了相同的结果。Juan,非常有趣。谢谢。我将在其他几个虚拟机上试用。我在
java-cp Clojure.jar Clojure.main中使用了裸Clojure REPL,但是当我在REPL-y客户端中试用它时,leiningen使用它连接到nREPL服务器,我看到了与您相同的情况。使用哪个在调用
println
后,我不认为抛出的异常会妨碍缓冲区的刷新。但我不知道为什么您会看到这种行为:(好的,知道了(我想),它看起来像是REPL-y首先在它自己的缓冲区中捕获整个表达式的结果,因此当出现异常时,它只打印该结果,而不是为stdout缓冲的结果。可以通过这一点观察到(map(fn[x](Thread/sleep 5000)(println“x”)x)[1 2 3]),即使println调用flush REPL-y,直到15秒后才打印任何内容。