Common Lisp多值返回机制存疑:是否应谨慎使用该特性?
Common Lisp多值返回的行为与使用建议
先明确回答你的代码疑问:在任何符合Common Lisp标准的实现中,(g)都会返回a和b两个值,不会只返回主值。
你提到的《Practical Common Lisp》里的那句话,重点要区分底层实现机制和语言语义标准:
- Peter Seibel说的“依赖具体实现”,指的是多值在底层(比如寄存器、栈)的传递方式,这部分是各实现可以自主选择的细节;
- 但多值的传递语义是标准强制规定的:所有返回子表单值的语言结构(比如函数调用、
progn的最后一个子表单等)必须完整传递子表单返回的所有多值。所以你的代码里,g调用f后,会把f的所有返回值原封不动地返回,这是确定的行为。
关于是否要谨慎使用多值返回:
- 多值返回是Common Lisp的核心特性,完全可以放心用,但要选对场景:
- 适合返回逻辑上紧密关联的多个值(比如
floor返回商和余数、decode-universal-time返回时间各字段),这种场景下用多值比包装成列表/结构体更高效,语义也更清晰; - 当需要把多值作为单一参数传递给函数时,要显式用
multiple-value-list转换为列表,或者用multiple-value-bind绑定到变量后再处理; - 避免在不必要的场景滥用,比如明明只需要一个返回值却刻意返回多个,会增加代码的理解成本。
- 适合返回逻辑上紧密关联的多个值(比如
附上你提到的原文引用和代码示例:
在《Practical Common Lisp》中,Peter Seibel提到:
多值返回的实现机制与函数参数传递机制一样,是依赖于具体实现的。几乎所有返回子表单值的语言结构都会“传递”多值,即返回子表单返回的所有值。因此,调用VALUES或VALUES-LIST的函数本身会返回多值——调用该函数的其他函数也会如此,依此类推。
你的代码示例(修正注释):
> (defun f () (values 'a 'b)) > (defun g () (f)) > (g) ; ==> a b (符合标准的实现均会返回两个值)
内容的提问来源于stack exchange,提问作者shynur
相关产品推荐
相关产品推荐

