質問

私たちは今日、私たちのコードの問題に出くわしましたが、このクロジュアの質問に答えることができませんでした。

Clojureは不純なコード(またはJavaコードへの呼び出し)を厳密にまたは怠zileに評価しますか?

副作用 +怠zyなシーケンスは奇妙な動作につながる可能性があるようです。


これが私たちが知っていることが質問につながったことです。

Clojureには怠zyなシーケンスがあります:

user=> (take 5 (range)) ; (range) returns an infinite list
(0 1 2 3 4)

Clojureには副作用があり、不純な機能があります。

user=> (def value (println 5))
5                               ; 5 is printed out to screen
user=> value
nil                             ; 'value' is assigned nil

また、ClojureはJavaオブジェクトを呼び出すことができます。これには、副作用が含まれる場合があります。ただし、副作用は怠zyな評価とは不十分に相互作用する可能性があります。

user=> (def my-seq (map #(do (println %) %) (range)))
#'user/my-seq
user=> (take 5 my-seq)                               
(0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
0 1 2 3 4)

そこで、最初の5つの要素を返しましたが、最初の31を印刷しました!

Javaオブジェクトの副作用方法を呼び出すと、同じ種類の問題が発生する可能性があると思います。これにより、コードについて推論し、何が起こるかを理解するのが本当に難しくなる可能性があります。


補助的な質問:

  • そのような状況に気をつけて防止するのはプログラマー次第ですか? (はい?)
  • シーケンスに加えて、Clojureは厳格な評価を実行しますか? (はい?)
役に立ちましたか?

解決

Clojureの怠zyなSEQチャンクは約30アイテムであるため、小さなオーバーヘッドがさらに減少します。それは純粋主義者の選択ではなく、実用的なものです。通常のソリューションについては、時間に1つの要素を実現するために、「Clojureの喜び」を参照してください。

怠zyなSeqは、遭遇した理由のために不純な機能にぴったりではありません。

Clojureは厳密に評価しますが、マクロでは物事は少し異なります。などのビルドン if 自然に評価を保持します。

他のヒント

怠zyな構造は、実装に何が参照されていても、実装に便利な場合は多かれ少なかれ評価されます。したがって、はい、必要に応じて慎重に怠zyなSEQを強制的に実現するのはプログラマー次第です。

厳格な評価とはどういう意味かわかりません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top