apply&funcall - 不同的结果

And*_*man 4 lisp clisp common-lisp ansi-common-lisp

ANSI Common Lisp.为什么我在最后一个案例中得到了另一个答案?

(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)
Run Code Online (Sandbox Code Playgroud)

Rai*_*wig 8

APPLY 期待作为参数:

  • 一个功能
  • 零... n个参数
  • 然后是最后的参数列表

该函数基本上会被调用 (list* 0-arg ... n-arg argument-list)

请注意,(list* '(1 2 3))评估为just (1 2 3).

参数在Common Lisp 中称为可扩展参数列表.

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)
Run Code Online (Sandbox Code Playgroud)

APPLY按设计使用这种可扩展的参数列表.例如(... 1 2 3 '(4 5)).随着FUNCALL你写的参数和往常一样:(... 1 2 3 4 5).

APPLY在Common Lisp中有一个目的:它允许使用计算参数列表调用函数.为了使这更方便,已经使用了可扩展参数列表的这种想法.例如在Emacs Lisp中它的工作原理相同.

想象一下,你有一个参数列表,你想在前面添加两个参数.

CL-USER 64 > (apply '+ args)
60

CL-USER 65 > (apply '+ 1 2 args)
63

CL-USER 66 > (apply '+ (append (list 1 2) args))
63
Run Code Online (Sandbox Code Playgroud)