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