лень работает не так, как ожидалось

(defn seq-trial
  []
  (map #(do (println "hello " %) (inc %)) (range 10)))

(take 3 (seq-trial))

в snippt код выше при оценке распечатывает следующее -

(привет 0 Привет 1 привет 2 привет 3 привет 4 привет 5 Здравствуйте 6 привет 7 привет 8 привет 9 1 2 3)

поскольку map возвращает ленивую последовательность, я ожидал, что это будет печатать только -

(привет 0 Привет 1 привет 2 1 2 3)

почему весь список оценивается здесь?

1 ответов


это из-за оптимизации производительности, называемой chunking. По существу последовательность реализуется в группах n элементы, называемые фрагментами. Это означает, что вам нужно позаботиться о любых побочных эффектах в вашей функции отображения. Конечный результат правильный, вы все равно получаете последовательность правильной длины, возвращаемой

размер куска по умолчанию-32, поэтому, если вы увеличите свой диапазон до значения больше, чем это, вы поймете, что происходит немного лучше:

user> (defn seq-trial
  []
  (map #(do (println "hello " %) (inc %)) (range 100)))

user> (take 3 (seq-trial))
hello  0 ; 32 item 'chunk' realized...
hello  1

...

hello  30
hello  31
(1 2 3)  ; the expected returned value

Если вам нужно избежать chunking есть опции доступен