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

В чем разница между функциями door dorun doseq и для?

В чем разница между функциями doall, dorun, doseq и for?

Я нашел некоторую информацию, разбросанную по всему Интернету, но я думаю, что было бы лучше централизовать эту информацию здесь.

4b9b3361

Ответ 1

dorun, doall и doseq - все для форсирования ленивых последовательностей, предположительно для получения побочных эффектов.

  • dorun - не удерживайте целую секцию в памяти во время форсирования, возвратите nil
  • doall - удерживать целую секцию в памяти при форсировании (т.е. все) и возвращать seq
  • doseq - то же самое, что и dorun, но дает вам шанс сделать что-то с каждым элементом, поскольку он принудительно; возвращает nil

for отличается тем, что он понимает список и не связан с принудительными эффектами. doseq и for имеют один и тот же синтаксис связывания, который может быть источником путаницы, но doseq всегда возвращает nil, а for возвращает ленивый seq.

Ответ 2

Вы можете видеть, как dorun и doall относятся друг к другу, глядя на (упрощенный) исходный код:

(defn dorun [coll]
  (when (seq coll) (recur (next coll))))

(defn doall [coll] (dorun coll) coll)
  • dorun пробегает последовательность, забывая ее, как она идет, в конечном итоге возвращая nil.
  • doall возвращает свой аргумент последовательности, теперь реализуемый dorun.

Аналогично, мы могли бы реализовать doseq в терминах dorun и for:

(defmacro doseq [seq-exprs & body]
  `(dorun (for ~seq-exprs [email protected])))

По какой-то причине производительность, возможно, не выполняется. Стандарт doseq записывается полностью, подражая for.