今日、私たちのコードで問題に遭遇し、この Clojure の質問に答えることができませんでした:
Clojure は不純なコード (または Java コードの呼び出し) を厳密に評価しますか、それとも遅延して評価しますか?
副作用 + 遅延シーケンスにより、奇妙な動作が発生する可能性があるようです。
質問につながったことがわかっていることは次のとおりです。
Clojure には遅延シーケンスがあります。
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 オブジェクトを呼び出すことができますが、これには副作用が含まれる場合があります。ただし、副作用は遅延評価とうまく相互作用しない可能性があります。
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 は厳密な評価を実行しますか? (はい?)