首先,让我们调用:
(mapcon (lambda (list) (print list) nil) '(1 2))
因为匿名函数一直返回NIL,所以结果列表是NIL;调用会打印:
(1 2)
(2)
因此,在您的示例中,当您调用 (mapcon #'g '(1 2)) 时,g 将首先使用 (1 2) 调用,然后使用 (2)。函数g 返回一个列表,mapcon 将它们连接起来。
通过显式计算每个部分,可以在 REPL 中复制所发生的事情:
USER> (mapcon #'list '(1 2))
((1 2) (2))
USER> (mapcon #'list '(2))
((2))
USER> (nconc ** *)
((1 2) (2) (2))
最后,(apply #'append list-of-lists) 使用参数列表调用 append。
append的签名是:
append &rest lists => result
这意味着如果l1、l2和l3是列表,则包含它们所有元素的列表是:
(append l1 l2 l3)
这里append 的参数存储在一个列表中,因此将任意参数列表传递给函数的方法是使用apply。所以这意味着(apply #'append lists) 连接列表中的所有列表,这就是为什么在你的情况下结果是(1 2 2 2)。
请注意,当参数的数量是任意的(可能很大)时,不建议使用apply,因为apply 受CALL-ARGUMENTS-LIMIT 的限制。另一种可能的方法是:
(loop for list in lists append list)