Вопрос

Мы наткнулись на вопрос в нашем коде сегодня и не смогли ответить на этот вопрос:

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 выполняет строгую оценку? (Да?)
Это было полезно?

Решение

Ленивые Seqs Clojure Chunk около 30 предметов, поэтому маленькая накладная головка еще больше уменьшается. Это не выбор пуриста, а практичный. Проконсультируйтесь с «радостью Clojure» для обычного решения, чтобы реализовать один элемент в момент времени.

Lazy SEQ не идеально подходит для нечистых функций по причине, с которой вы столкнулись.

Clojure также будет оцениваться строго, но с макросами вещи немного по -другому. Встроенные такие как if Естественно проведет оценку.

Другие советы

Ленивые конструкции оцениваются более или менее, когда это удобно для реализации, независимо от того, что в них упоминалось. Так что, да, программист должен быть осторожным и принудительно реализовать ленивые SEQ, когда это необходимо.

Я понятия не имею, что вы имеете в виду под строгой оценкой.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top