Різниця між дозою і за Clojure


105

Яка різниця між дозою і в Клоджуре? Наведіть кілька прикладів, коли ви вирішили використовувати один над іншим?

Відповіді:


167

Різниця полягає в тому, що forбудується лінива послідовність і повертає її, а doseqдля виконання побічних ефектів і повертає нуль.

user=> (for [x [1 2 3]] (+ x 5))
(6 7 8)
user=> (doseq [x [1 2 3]] (+ x 5))
nil
user=> (doseq [x [1 2 3]] (println x))
1
2
3
nil

Якщо ви хочете побудувати нову послідовність на основі інших послідовностей, використовуйте для. Якщо ви хочете зробити побічні ефекти (друк, запис у базу даних, запуск ядерної боєголовки тощо) на основі елементів з деяких послідовностей, використовуйте doseq.


11
тепер це багато побічних ефектів ... запуск ядерної боєголовки :)
Марк

6
Дякую! Я володів моїми (давно зниклими) волосся з "за", щоб ніколи не стріляти з ядерних боєголовок над моїм списком предметів. "doseq" впевнений.
Ю. Шень

Це відмінний спосіб поставити відмінність.
jskulski

60

Зауважте також, що doseqпрагне, поки forледачий. Приклад відсутній у відповіді Рейна:

(for [x [1 2 3]] (println x))

У системі REPL це, як правило, робити те, що ви хочете, але це, в основному, збіг обставин: REPL змушує ліниву послідовність, що створюється for, викликаючи printlns. У неінтерактивному середовищі нічого ніколи не буде надруковано. Ви можете бачити це в дії, порівнюючи результати

user> (def lazy (for [x [1 2 3]] (println 'lazy x)))
#'user/lazy

user> (def eager (doseq [x [1 2 3]] (println 'eager x)))
eager 1
eager 2
eager 3
#'user/eager

Оскільки defформа повертає створений новий var, а не пов'язане з ним значення, REPL нічого не надрукує, і lazyбуде посилатися на нереалізований lazy-seq: жоден з його елементів взагалі не був обчислений. eagerбуде посилатися nil, і вся його друк буде зроблена.


Яким чином дозік поводиться з оцінкою нескінченної лінивої послідовності? погана ідея? називати це лише на кінцевих послідовностях, нетерплячих чи ледачих?
johnbakers

@johnbakers Він блокується назавжди, поки оцінка не буде перервана. Clojure ніколи не намагається обробити нескінченні послідовності інакше, ніж кінцеві послідовності.
Радон Росборо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.