Когда вы используете «применить» и когда «funcall»?

Common Lisp HyperSpec говорит вfuncall запись, которая

(funcall function arg1 arg2 ...) 
==  (apply function arg1 arg2 ... nil) 
==  (apply function (list arg1 arg2 ...))

Поскольку они как-то эквивалентны, когда бы вы использовалиapply, и когдаfuncall?

Ответы на вопрос(3)

Что ж, я думаю, что хорошее практическое правило было бы следующим: используйте apply, когда вы не можете использовать funcall: последний более понятен, но он также менее общий, чем apply, поскольку он не позволяет вам вызывать функцию, число аргументов которой равно только известно во время выполнения.

Конечно, это только хорошая практика, и вымог систематически делайте это уродливым способом (систематически используя apply), но, как вы, вероятно, заметили, использование уродливого способа, когда доступен очень похожий, но более чистый способ, не очень распространено - lisp-y.

Пример функции, которую нужно применить вместо funcall: вы могли бы реализовать карту таким образом, чтобы(map #'+ '(1 2) '(2 3)) а также(map #'+ '(1 2) '(2 3) '(3 4)) оба работают (что имеет место со стандартной функцией) без использования apply (или eval, который обманывает)?

РЕДАКТИРОВАТЬКак было указано, было бы глупо писать:(funcall func (first list) (second list) (third list) etc.) вместо(apply func list).

Решение Вопроса

Вы должны использоватьfuncall если у вас есть один или несколько отдельных аргументов иapply если у вас есть свои аргументы в списке

(defun passargs (&rest args) (apply #'myfun args))

или же

(defun passargs (a b) (funcall #'myfun a b))

apply полезно, когда список аргументов известен только во время выполнения, особенно когда аргументы читаются динамически как список. Вы все еще можете использоватьfuncall здесь, но вы должны распаковать отдельные аргументы из списка, что неудобно. Вы также можете использоватьapply лайкfuncall передавая отдельные аргументы. Единственное, что для этого требуется, это то, что последний аргумент должен быть списком:

> (funcall #'+ 1 2)
3
> (apply #'+ 1 2 ())
3

Ваш ответ на вопрос