Подтвердить что ты не робот

В чем смысл lazy-seq в clojure?

Я просматриваю пример последовательности Fibonacci clojure code:

 (def fibs (lazy-cat [1 2] (map + fibs (rest fibs))))

Я вообще понимаю, что происходит, но не получаю точку lazy-cat.  Я знаю, что lazy-cat - это макрос, переводящий что-то вроде этого:

(def fibs (concat (lazy-seq [1 2]) (lazy-seq (map + fibs (rest fibs))))) 

Что именно достигается lazy-seq? Он все равно будет оцениваться лениво даже без lazy-seq? Это строго для целей кэширования?

EDIT: Спасибо за ответы. Моя путаница заключалась в том, что он работал с простым concat из REPL, потому что у меня было предыдущее связывание с fibs в области.

4b9b3361

Ответ 1

lazy-seq на [1 2] не требуется, но на самом деле не больно.

lazy-seq on (map + fibs (rest fibs)) является существенным; без него вызов функции будет оцениваться до того, как fibs привязан к значению, что вызовет исключение. Упаковывая его в lazy-seq, вызов будет отложен до тех пор, пока значение не понадобится, и fibs будет иметь значение в этой точке.

Ответ 2

Как я понимаю (и я признаю, что все еще являюсь относительным новичком в Clojure!), если вы попробуете следующее:

(def fibs (concat [1 2] (map + fibs (rest fibs))))

Тогда это не сработает, потому что фибры еще не связаны, и поэтому две более поздние ссылки на него не работают.

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