1) Удобство. С математическими функциями, такими как +
, было бы неприятно оборачивать все в последовательности, когда вы просто пытаетесь выполнить некоторые вычисления.
2) Эффективность. Упаковка всего с коллекциями / последовательностями также была бы неэффективной, сначала необходимо создать последовательность, а затем распаковать ее во время выполнения вместо того, чтобы искать нужную функцию Java во время компиляции .
3) Ожидания. Вот как эти функции работают в других Лиспах и аналогично, с несколько другим синтаксисом, в других функциональных языках, так что это разумное ожидание для людей, приезжающих в Clojure. Я бы сказал, что идиоматический способ применения таких функций, как +
к последовательности, в других функциональных языках заключается в использовании reduce
или foldl
/ foldr
, так что это также соответствует тому, как Clojure обрабатывает это.
4) Гибкость. Тот факт, что эти функции могут использоваться с функциями более высокого порядка, такими как map
, делает их более удобными для использования, если они являются вариативными. Скажем, у вас есть три вектора, и вы хотите применить функцию к элементам в одной и той же позиции. Если ваша функция является переменной, то вы можете просто использовать карту с несколькими коллекциями (тогда карта также должна быть переменной;)):
(map + [1 2 3 4] [2 3 4 5] [3 4 5 6])
; [6 9 12 15]
Это намного удобнее, чем если бы все эти функции просто собирали коллекции.
Идиоматическое использование: (Отредактировано после превосходного комментария котарака)
Это зависит от функции, если вы должны использовать reduce
или apply
.
Для математических функций (+,-,*,/,etc.)
, которые принимают 2 аргумента в мире Java reduce
, имеет больше смысла, так как он может напрямую использовать версию Java с 2 аргументами. С apply
они как бы делают неявное reduce
( Функция добавляет два аргумента, а затем возвращается с результатом, следующим аргументом и остальными.
Для str
использование apply
, вероятно, более эффективно. Когда str
вызывается с более чем одним аргументом, он создает StringBuilder, добавляет к нему все аргументы, а затем создает строку. При использовании reduce
StringBuilder будет создан n-1 раз и будет добавлять только одну строку каждый раз. Это как в Шлемиеле * шутке маляра , что приводит к сложности O (n ^ 2).
Пока вердикт: использование apply
с математическими функциями не повредит, но использование reduce
с str
может быть довольно дорогим.