Самое важное, что вам нужно знать, это то, что последовательности в Clojure ленивы. Это означает, что элементы в последовательности оцениваются только тогда, когда они необходимы. Это позволяет работать с бесконечными последовательностями.
В большинстве случаев это именно то, что вам нужно, но это может сбивать с толку, когда вы на самом деле не интересуетесь значениями элементов последовательности, но побочными эффектами функций, которые создают элементы последовательности. В вашем примере последовательность состоит из 100 возвращаемых значений функции println
, то есть 100 раз nil
- не очень интересно. Но у функции println
есть побочный эффект печати «Hello World» на стандартный вывод.
Проблема в том, что если вы никогда ничего не делаете с элементами в последовательности, функции println
никогда не оцениваются и строки не печатаются. Это вроде работает в REPL, потому что P в REPL означает print - возвращаемое значение выражения, которое вы ввели, печатается. Чтобы напечатать всю последовательность, она должна быть оценена, поэтому вы видите кучу «Hello World», но также и кучу nils
. Если вы запустите код вне REPL (без использования возвращаемого значения), вы не увидите Hello Worlds.
Если вас интересуют побочные эффекты ваших функций создания предметов, вы можете использовать doall
или doseq
. doall
заставляет всю последовательность быть оцененной и возвращает ее:
(doall (for [a (range 100)] (println "Hello World")))
doseq
не возвращает последовательность (возвращается nil
) и имеет синтаксис, такой как for
:
(doseq [a (range 100)] (println "Hello World"))
Также обратите внимание, что вам действительно нужно указать желаемое количество (100) только один раз. Функция range
уже создает последовательность из 100 элементов. Предложение :while
в вашем коде является избыточным, равно как и функция take
(получение первых 100 элементов из последовательности, содержащей 100 элементов, мало что дает).
Надеюсь, это поможет!