Вы могли бы использовать применить , если количество аргументов, передаваемых функции, неизвестно во время компиляции (извините, я плохо знаю синтаксис Clojure, прибегая к Scheme):
(define (call-other-1 func arg) (func arg))
(define (call-other-2 func arg1 arg2) (func arg1 arg2))
Пока количество аргументов известно во время компиляции, вы можете передать их напрямую, как это сделано в примере выше. Но если количество аргументов неизвестно во время компиляции, вы не можете этого сделать (ну, вы можете попробовать что-то вроде):
(define (call-other-n func . args)
(case (length args)
((0) (other))
((1) (other (car args)))
((2) (other (car args) (cadr args)))
...))
, но это скоро станет кошмаром. Вот где apply входит в картину:
(define (call-other-n func . args)
(apply other args))
Он принимает любое количество аргументов, содержащихся в списке, указанном в качестве последнего аргумента для него,
Обычным шаблоном для операций типа применить является объединение функции, предоставляемой во время выполнения, с набором аргументов, то же самое.
Я недостаточно проделал с clojure, чтобы быть уверенным в тонкостях этого конкретного языка, чтобы сказать, будет ли использование apply в этом случае строго необходимым.
Термины Lisp-1 и Lisp-2 относятся к тому, находятся ли функции в одном пространстве имен как переменные.
В Lisp-2 (то есть в двух пространствах имен) первый элемент в форме будет оцениваться как имя функции - даже если на самом деле это имя переменной со значением функции. Поэтому, если вы хотите вызвать функцию переменной, вам нужно передать переменную другой функции.
В Lisp-1, например в Scheme и Clojure, переменные, которые оценивают функции, могут находиться в исходной позиции, поэтому вы не должны '
применить
в основном разворачивает последовательность и применяет функцию к ней как к отдельным аргументам.
Вот пример:
(apply + [1 2 3 4 5])
Возвращает 15. Вместо этого она расширяется до (+ 1 2 3 4 5)
. из (+ [1 2 3 4 5])
.