Здесь проблема, с которой я сталкиваюсь в Clojure:
user=> (max [3 4 5 6 7])
[3 4 5 6 7] ; expected '7'
Некоторые функции не выполняют то, что я ожидаю!
Здесь одно решение с использованием apply
:
user=> (apply max [3 4 5 6 7])
7
Другими примерами являются concat
и min
.
Мой вопрос, как новичок Clojure, почему эти функции вариативны? Я ожидал, что они будут работать над последовательностями. Использует ли apply
лучший/идиоматический способ получить то, что я хочу?
Примечание: Я не пытаюсь сказать, что это плохо, чтобы иметь вариативные функции, или что есть лучший способ. Я просто хочу знать, соблюдается ли правило или соглашение, или если есть определенные преимущества для такого подхода, о котором я должен знать.
Изменить: Я думаю, что исходный вопрос был неясным. Вот что я имел в виду:
В других языках программирования, которые я использовал, есть monoid-подобные операции, такие как добавление чисел, поиск большего элемента, объединение списков.
Для этих операций часто используются два варианта использования:
1) объединение двух элементов, используя функцию, которая принимает два аргумента
2) объединение 0 в n элементов, используя функцию, которая принимает список (или последовательность) элементов
Функция для второго случая может быть построена из функции для первого случая (часто используя reduce
).
Однако Clojure добавляет третий вариант использования:
3), объединяющее от 0 до n элементов, используя вариационную функцию
Итак, вопрос в том, почему Clojure добавить этот третий случай?
Пол отвечает, что:
- это позволяет более гибкий код
- Есть исторические силы на работе