为什么for函数没有执行
Why the for function is not executed
我是clojure初学者,有一个困惑的问题:
(do (println "ok") (for [x [1 2 3]] (println x)))
输出:
行
1个
2个
3
这个我能理解,但是
(do (for [x [1 2 3]] (println x)) (println "ok"))
输出:
行
无
为什么for函数没有执行?
简而言之:do 宏计算所有参数,return 是最后一个参数的值,这迫使惰性序列的元素实现。
我假设您在 REPL 中评估了两个表达式。
由于 for 宏,第一个表达式 return 是惰性序列。 REPL 强制计算 returned 值(因此它可以显示计算结果)因此序列的每个元素都通过打印到屏幕的副作用来实现。
在第二种情况下,return 值为 nil
,因为 do form was a println 调用中的最后一个表达式。在这种情况下也创建了惰性序列,但它的元素从未实现,因为从未使用过该值。
如果你想强制计算一个序列,你可以使用doall或dorun。如果你对序列不感兴趣,只需要一个循环结构,你可以使用 doseq 而不是 for.
您示例中的 (println x)
形式是 side-effects,只有实现 for
惰性序列才会出现。
这是重新格式化的第一个示例:
(do
(println "ok")
(for [x [1 2 3]]
(println x)))
do
依次计算表达式,returns 最后一个的值。这里的最后一个表达式是一个惰性序列。如果您在 REPL 中评估它,惰性序列将实现打印其元素(给出值 (nil nil nil)
)并导致 side-effects 打印 1
2
3
.
这是重新格式化的第二个例子:
(do
(for [x [1 2 3]]
(println x))
(println "ok"))
再次do
依次计算表达式。第一个是惰性序列,但它的值未被使用,因此从未实现。这意味着打印 1
2
3
的 side-effects 不会发生。
其他答案已经给出了很好的背景。如果您需要 for
的高级功能但不想要懒惰的方面,只需将整个内容包装在 (vec ...)
形式中:
(vec (for [x [1 2 3]]
(println x)))
这已经在 forv
宏中为您完成,可以 be seen here。
我是clojure初学者,有一个困惑的问题:
(do (println "ok") (for [x [1 2 3]] (println x)))
输出: 行 1个 2个 3
这个我能理解,但是
(do (for [x [1 2 3]] (println x)) (println "ok"))
输出: 行 无
为什么for函数没有执行?
简而言之:do 宏计算所有参数,return 是最后一个参数的值,这迫使惰性序列的元素实现。
我假设您在 REPL 中评估了两个表达式。
由于 for 宏,第一个表达式 return 是惰性序列。 REPL 强制计算 returned 值(因此它可以显示计算结果)因此序列的每个元素都通过打印到屏幕的副作用来实现。
在第二种情况下,return 值为 nil
,因为 do form was a println 调用中的最后一个表达式。在这种情况下也创建了惰性序列,但它的元素从未实现,因为从未使用过该值。
如果你想强制计算一个序列,你可以使用doall或dorun。如果你对序列不感兴趣,只需要一个循环结构,你可以使用 doseq 而不是 for.
您示例中的 (println x)
形式是 side-effects,只有实现 for
惰性序列才会出现。
这是重新格式化的第一个示例:
(do
(println "ok")
(for [x [1 2 3]]
(println x)))
do
依次计算表达式,returns 最后一个的值。这里的最后一个表达式是一个惰性序列。如果您在 REPL 中评估它,惰性序列将实现打印其元素(给出值 (nil nil nil)
)并导致 side-effects 打印 1
2
3
.
这是重新格式化的第二个例子:
(do
(for [x [1 2 3]]
(println x))
(println "ok"))
再次do
依次计算表达式。第一个是惰性序列,但它的值未被使用,因此从未实现。这意味着打印 1
2
3
的 side-effects 不会发生。
其他答案已经给出了很好的背景。如果您需要 for
的高级功能但不想要懒惰的方面,只需将整个内容包装在 (vec ...)
形式中:
(vec (for [x [1 2 3]]
(println x)))
这已经在 forv
宏中为您完成,可以 be seen here。