当阅读其他开发人员编写的Commom Lisp代码时,我注意到其中一些
调用VALUES访问器,而不提供返回值为空或可忽略的最后一种定义形式的任何参数。
例子:
(defun definition-whose-return-values-are-neglectable ()
... Some s-expressions ...
(values))
将此表单作为此类定义中的最后一个表达式添加(对于编译器来说,在性能等方面)有什么好处吗?
最佳答案
最后一个表单的优点或主要用例是:
当返回值对定义没有意义时的自文档代码
通常,为了避免开发工具处理或保留对
忽略或不必要的结果;
明确地:
为了避免在REPLs中打印长序列或无限序列,如果您有(values)
设置为*print-circle*
,t
设置为*print-length*
,nil
设置为*print-level*
,
或类似的任何特定于实现的参数
由于no值被视为nil
,并将*
设置为空列表
在快板cl的ide中,nil
和Listeners
保留对结果的引用,直到它们被清除1
在LispWorks的IDE中,Trace dialog工具在
输出数据视图直到它们被清除
在黏液中,REPL会保留Tracer结果的引用
直到他们被清除
非优势/非问题:
有些编译器生成的指令更少,有些编译器生成的指令更多,但是除非
你在计算字节和/或周期,这可以忽略不计
您已经不需要返回任何值,例如:
当您希望调用者区分返回值的数量时
这可能也暴露了定义的糟糕设计
当结果应该用于
presentations表格
这可能也暴露了调用者的糟糕设计,它实际上有
形式之间的影响
除了消除副作用或允许
在整个治疗前后发生的副作用nil
问题:
通常,它从定义中禁用尾部调用优化
但是,一个足够聪明的编译器可能会检测到没有值定义的尾部调用,
通常在/
multiple-value-call
s/multiple-value-call
s的帮助下,
并在这些调用中应用优化
这并非没有其他定义被更改的风险,所以我的猜测是
没有实现,不是吗
一你可以通过设置一个听众的历史来清除他在快板CL中的历史
空列表的大纲内容:
(setf (cg:range (cg:find-component
:history-outline
(first (cg:toolbars ide.base:*listener-window*))))
'())