副作用最优化 [英] Side effect optimized out
问题描述
我是clojure的新手,有时会遇到问题。
I am new to clojure and at some moment I faced with the problem.
我的程序中有以下代码:
I have such code in my program:
(let [ ... ]
(map (fn [[v f]] (do-side-effect v f)) {:v1 f1, :v2 f2})
(do-the-job ...))
此 do-副作用-code>可以是例如
intern等另一个副作用函数的
。问题是不会发生副作用。 println
This do-side-effect
can be, for example, println
of another side effect function like intern
. The problem is that side effect doesn't happen.
但是如果我将行更改为
(println (map #(fn [[v f]] (do-side-effect v f)) {:v1 f1, :v2 f2}))
然后一切正常。
所以我最后想到的是clojure
只是优化了 map
,因为
认为结果没有用,因为我不要使用它。
Then everything is ok.
So the last idea i came to is that clojure
just optimize out the map
because
it think that it's result is useless because I don't use it.
万一这种情况真的发生了,我该如何证明这种形式的
会产生副作用以防止编译器对其进行优化?
In case if this actually happens, how can I show clojure that this form can have side effects to prevent compiler from optimizing it out?
如果它是一个错误,如何找到错误所在?
In case if it's a bug, how can I find where the bug is?
推荐答案
map
很懒。它并不是要直接用于副作用,它只会在消耗它们时产生值。
map
is lazy. It is not meant to be used directly for side effects, and it only produces values when they are consumed.
您可以使用 dorun
强制实现这些值,即使您不使用它们,也可以使用 doseq
代替map doseq
用于产生副作用,与map不会花费时间来构造您永远不会访问的对象。
You can use dorun
to force the values to be realized, even if you are not consuming them, or use doseq
instead of map, doseq
is intended to be used for side effects, and unlike map won't spend time constructing objects you won't ever access.
这篇关于副作用最优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!