Common Lisp中&rest参数和列表之间的区别

pra*_*pes 2 lisp common-lisp

(defun highest (lat)
    (cond
        ((null lat) nil)
        ((null (cdr lat)) (car lat))
        (T (higher (car lat) (highest (cdr lat))))))

(defun higher (a1 a2)
    (cond
        ((> a1 a2) a1)
        (T a2)))
Run Code Online (Sandbox Code Playgroud)

此功能按预期工作:

> (highest '(3 5 1 2 3))    
3. Trace: (HIGHEST '(3 5 1 2 3))
4. Trace: (HIGHEST '(5 1 2 3))
5. Trace: (HIGHEST '(1 2 3))
6. Trace: (HIGHEST '(2 3))
7. Trace: (HIGHEST '(3))
7. Trace: HIGHEST ==> 3    
6. Trace: HIGHEST ==> 3
5. Trace: HIGHEST ==> 3
4. Trace: HIGHEST ==> 5    
3. Trace: HIGHEST ==> 5
Run Code Online (Sandbox Code Playgroud)

但是,如果我将参数更改为&rest:

(defun highest (&rest args)
    (cond
        ((null args) nil)
        ((null (cdr args)) (car args))
        (T (higher (car args) (highest (cdr args))))))
Run Code Online (Sandbox Code Playgroud)

它的行为不一样.

> (highest 3 5 1 2 3)
3. Trace: (HIGHEST '3 '5 '1 '2 '3)
4. Trace: (HIGHEST '(5 1 2 3))
4. Trace: HIGHEST ==> (5 1 2 3)
*** - >: (5 1 2 3) is not a real number
Run Code Online (Sandbox Code Playgroud)

编辑:对不起,我忘了提到我在第二种情况下传递了一个原子的参数.我编辑了这个问题,使其更加清晰.

Tho*_*her 5

尝试在呼叫前评估(追踪最高)(最高3 2 10).然后,您将看到第二个调用如下所示:(最高'(2 10))然后&rest参数看到一个恰好是列表的对象.

要更正此问题,请使用APPLY.APPLY就像funcall,但它的最后一个参数必须是一个列表,并被视为'拼接到'函数调用.像这样:(应用#'最高(cdr args))