Как лень Clojure взаимодействует с вызовами Java / нечистого кода? - PullRequest
8 голосов
/ 19 октября 2011

Сегодня мы столкнулись с проблемой в нашем коде и не смогли ответить на этот вопрос 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 выполняет строгую оценку? (Да?)

Ответы [ 2 ]

8 голосов
/ 19 октября 2011

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

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

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

2 голосов
/ 19 октября 2011

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

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

...