apply & funcall - os diferentes resultados
-
21-12-2019 - |
Pergunta
Lisp comum ANSI.Por que recebo outra resposta no último caso?
(list 1 2 3 nil) ; (1 2 3 nil)
(funcall (function list) 1 2 3 nil) ; (1 2 3 nil)
(apply (function list) '(1 2 3 nil)) ; (1 2 3 nil)
(apply (function list) 1 2 3 nil) ; (1 2 3)
Solução
APPLY
espera como argumentos:
- uma função
- zero...n argumentos
- e depois uma lista de argumentos no final
A função será basicamente chamada com o resultado de (list* 0-arg ... n-arg argument-list)
Observe que (list* '(1 2 3))
avalia apenas (1 2 3)
.
Os argumentos são chamados lista de argumentos espalháveis em Lisp comum.
CL-USER 60 > (apply (function list) 1 2 3 nil)
(1 2 3)
CL-USER 61 > (apply (function list) (list* 1 2 3 nil))
(1 2 3)
CL-USER 62 > (apply (function list) (list* '(1 2 3)))
(1 2 3)
APPLY
usa uma lista de argumentos distribuível por design.Por exemplo (... 1 2 3 '(4 5))
.Com FUNCALL
você tem que escrever os argumentos como de costume: (... 1 2 3 4 5)
.
APPLY
tem um único propósito no Common Lisp:permite que funções sejam chamadas com listas de argumentos computadas.Para tornar isso um pouco mais conveniente, esta ideia de lista de argumentos distribuíveis foi usada.Funciona da mesma forma, por exemplo, no Emacs Lisp.
Imagine que você tem uma lista de argumentos e deseja adicionar dois argumentos na frente.
CL-USER 64 > (apply '+ args)
60
CL-USER 65 > (apply '+ 1 2 args)
63
CL-USER 66 > (apply '+ (append (list 1 2) args))
63