Clojure и Leiningen: почему в этом примере необходимо использовать doall? - PullRequest
0 голосов
/ 27 мая 2018

В настоящее время я использую Leiningen для изучения Clojure, и меня смущает требование doall для запуска этой функции:

;; take a function (for my purposes, println for output formatting) and repeat it n times
(defn repeat [f n] (for [i (range n)] (f)))

(repeat println 2) прекрасно работает в сеансе REPL, ноне при работе с lein run, если я не включаю оболочку doall.(doall (repeat println 2)) работает, и мне любопытно, почему.Без этого lein run не показывает две пустые строки в выводе.

У меня также есть:

(defmacro newPrint1 [& args] `'(println ~args))
(defmacro newPrint2 [& args] `'(println ~@args))

Первая функция, которую я подумал о себе.Следующие два макроса являются примерами из обучающего видео, которому я следую на Udemy.Даже если я оберну вызовы макроса с помощью doall, например (doall (newPrint1 1 2 3)), lein run не выдаст никакого вывода, но (newPrint1 1 2 3) в сеансе REPL терминала выдаст желаемый вывод (clojure.core/println (1 2 3)), как это происходит в видеоуроке.Почему doall здесь не работает?

1 Ответ

0 голосов
/ 27 мая 2018

for создает ленивую последовательность.Эта ленивая последовательность возвращается.P in REPL (read eval Print loop) печатает последовательность, реализуя ее.Для реализации запускается код для создания каждого элемента.

Если вы не используете последовательность, она не реализуется, поэтому код никогда не запускается.В неинтерактивном использовании это, скорее всего, так.Как уже отмечалось, doall форсирует реализацию.

Если вы хотите получить побочные эффекты, doseq часто лучше подходит, чем for.

...