Chúng tôi đã tình cờ gặp sự cố trong mã của chúng tôi hôm nay và không thể trả lời câu hỏi Clojure này:Sự lười biếng của Clojure tương tác với các cuộc gọi đến mã Java/không tinh khiết như thế nào?
Clojure có đánh giá mã không đúng (hoặc gọi tới Java) không?
Dường như tác dụng phụ + trình tự lười biếng có thể dẫn đến hành vi lạ.
Đây là những gì chúng ta biết rằng dẫn đến câu hỏi:
Clojure có chuỗi lười biếng:
user=> (take 5 (range)) ; (range) returns an infinite list
(0 1 2 3 4)
Và Clojure có tác dụng phụ và chức năng bất tịnh:
user=> (def value (println 5))
5 ; 5 is printed out to screen
user=> value
nil ; 'value' is assigned nil
Ngoài ra, Clojure có thể thực hiện các cuộc gọi đến các đối tượng Java, có thể bao gồm các tác dụng phụ. Tuy nhiên, tác dụng phụ có thể tương tác kém với đánh giá lười biếng:
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)
Vì vậy, nó trả lại 5 yếu tố đầu tiên, nhưng in 31 đầu tiên!
Tôi giả định cùng một loại vấn đề có thể xảy ra nếu gọi các phương thức tác dụng phụ trên các đối tượng Java. Điều này có thể làm cho nó thực sự khó khăn để lý luận về mã và tìm ra những gì sẽ xảy ra.
câu hỏi phụ trợ:
- là nó lên đến các lập trình viên để xem ra cho và ngăn chặn tình huống như vậy? (Có?)
- Bên cạnh chuỗi, Clojure có thực hiện đánh giá nghiêm ngặt không? (Có?)
Đây không phải là cách trộn lẫn các tác dụng phụ và câu hỏi lười biếng - đây là "whoa, thật kỳ lạ, tại sao điều đó lại xảy ra và chúng ta tránh điều đó như thế nào trong tương lai?" câu hỏi. Tôi có đúng trong việc giải thích câu trả lời của bạn là: Clojure đánh giá không tinh khiết/các cuộc gọi Java một cách nghiêm túc, đó là trách nhiệm của lập trình viên, và không pha trộn không tinh khiết với sự lười biếng? –
@MattFenwick, về cơ bản Clojure luôn đánh giá đúng. Lazy seqs về cơ bản sử dụng các thủ thuật tương tự như python với máy phát điện của họ, vv .. Nghiêm ngặt evals trong quần áo lười biếng. :) – progo