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
Clojure 菜鸟:“你是谁?”;至于;函数中的循环以意外的方式运行_Clojure_Leiningen - Fatal编程技术网

Clojure 菜鸟:“你是谁?”;至于;函数中的循环以意外的方式运行

Clojure 菜鸟:“你是谁?”;至于;函数中的循环以意外的方式运行,clojure,leiningen,Clojure,Leiningen,我已经用Java和Perl开发了很长时间,但我想学习一些新的东西,所以我开始研究clojure。我尝试的第一件事是解决河内塔之谜,但我的漂亮打印函数出现了奇怪的行为。基本上,当我使用“lein run”运行for循环时,它从未被输入,但当我从repl运行它时,它似乎工作得很好。下面是一个简单的例子: (ns test-app.core (:gen-class)) (defn for-print "Print the same thing 3 times" [ p-string ]

我已经用Java和Perl开发了很长时间,但我想学习一些新的东西,所以我开始研究clojure。我尝试的第一件事是解决河内塔之谜,但我的漂亮打印函数出现了奇怪的行为。基本上,当我使用“lein run”运行for循环时,它从未被输入,但当我从repl运行它时,它似乎工作得很好。下面是一个简单的例子:

(ns test-app.core
  (:gen-class))

(defn for-print
  "Print the same thing 3 times"
  [ p-string ]
  (println (str "Checkpoint: " p-string))
  (for
    [x [1 2 3]]
    (printf "FOR: %s\n" p-string)
))


(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (for-print "Haldo wurld!"))
当我用'lein run'运行这个时,我只看到来自“Checkpoint”println的输出。如果我去掉那一行,我就不会得到任何输出。但是,如果我运行'lein repl',然后键入(-main),它会按预期打印字符串3次:

test-app.core=> (-main)
Checkpoint: Haldo wurld!
(FOR: Haldo wurld!
FOR: Haldo wurld!
FOR: Haldo wurld!
nil nil nil)
test-app.core=> 

这是怎么回事?我有一种感觉,我正在以错误的方式处理这个问题,试图用我过去的Perl/Java思维来编写clojure。将同一任务运行一定次数的惯用方法是什么?

for循环返回一个仅根据需要计算的惰性序列

当您在
repl
中运行程序时,将实现for result,以便在屏幕上显示结果

但是当您使用
运行时,lein run
结果从未使用过,因此无法实现收集

你有两个选择:

1) 使用
doall
for
循环之外执行强制延迟序列实现

例:

2) 由于您只是打印,这是一种副作用,而不是真正创建一个集合,因此您可以使用
doseq.

例:


for
循环返回的是一个仅在需要时才计算的惰性序列

当您在
repl
中运行程序时,将实现for result,以便在屏幕上显示结果

但是当您使用
运行时,lein run
结果从未使用过,因此无法实现收集

你有两个选择:

1) 使用
doall
for
循环之外执行强制延迟序列实现

例:

2) 由于您只是打印,这是一种副作用,而不是真正创建一个集合,因此您可以使用
doseq.

例:


Clojure
for
不是命令式循环(您应该完全避免在Clojure中考虑循环),它是一个列表理解,返回惰性序列。它用于创建序列,而不是打印任何内容。你可以意识到这一点,并让它发挥作用,但这是一条糟糕的道路

正如Guillermo所说,您正在寻找针对副作用而设计的
doseq
宏。这可能是你的案例中最惯用的Clojure


在我看来,Clojure中最类似于命令式循环的构造是使用loop/recur进行的尾部递归。尽管如此,它在Clojure中还是相当低级的构造,当然不应该以命令式循环的方式使用。更好地了解函数式编程原理以及Clojure核心函数。试图将Java/Perl思想转移到Clojure可能会伤害您。

Clojure
for
不是一个命令式循环(您应该完全避免在Clojure中考虑循环),它是一个列表理解,返回惰性序列。它用于创建序列,而不是打印任何内容。你可以意识到这一点,并让它发挥作用,但这是一条糟糕的道路

正如Guillermo所说,您正在寻找针对副作用而设计的
doseq
宏。这可能是你的案例中最惯用的Clojure


在我看来,Clojure中最类似于命令式循环的构造是使用loop/recur进行的尾部递归。尽管如此,它在Clojure中还是相当低级的构造,当然不应该以命令式循环的方式使用。更好地了解函数式编程原理以及Clojure核心函数。试图将Java/Perl思想转移到Clojure可能会伤害您。

其他答案是正确的,并提供了详细信息。我想补充一些可能有用的更高层次的澄清。在大多数语言中,“for”表示“对于这样或那样的条件,执行这样或那样的操作(可能是任意类型的,包括副作用)。“这种事情可以在Clojure中完成,我见过有经验的Clojure程序员在有用和方便的时候做。然而,使用带有副作用的循环通常不利于语言的优势。因此,在Clojure中,“for”一词在大多数语言中有不同的含义:生成(惰性)序列。它的意思是“对于这些输入,当/while/etc.它们满足这样或那样的条件时,临时绑定到这些变量,通过以这样或那样的方式处理每组值来生成(惰性)序列。”

其他答案是正确的,并提供了详细信息。我想补充一些可能有用的更高层次的澄清。在大多数语言中,“for”表示“对于这样或那样的条件,执行这样或那样的操作(可能是任意类型的,包括副作用)。“这种事情可以在Clojure中完成,我见过有经验的Clojure程序员在有用和方便的时候做。然而,使用带有副作用的循环通常不利于语言的优势。因此,在Clojure中,“for”一词在大多数语言中有不同的含义:生成(惰性)序列。它的意思是“对于这些输入,当/while/etc.它们满足这样或那样的条件时,临时绑定到这些变量,通过以这样或那样的方式处理每组值来生成(惰性)序列。”

感谢您的回答。这让我明白了很多。谢谢你的回答。这对我来说是件好事。
(defn for-print
 "Print the same thing 3 times"
 [ p-string ]
 (println (str "Checkpoint: " p-string))
 (doall (for
    [x [1 2 3]]
    (printf "FOR: %s\n" p-string))))
  (defn for-print
  "Print the same thing 3 times"
  [ p-string ]
  (println (str "Checkpoint: " p-string))
  (doseq [x [1 2 3]]
   (printf "FOR: %s\n" p-string)))