公之于世的 once-only 被我发现bug?

Practical Common Lisp 书上提及的防止 参数被多次求值的宏once-only 算是烧了我不少脑汁总算是领会了,但是发现了一个不小的bug!!


下面是另外一个页面的引用他这代码,类似:

结果是如果我的 body 有多行代码,这个宏只会返回最后一行,所以中间那几行代码

`(incf ,x 10)

不会运行:


可能觉得他本来就预料只执行/返回一行代码,如果要多行那就用 (progn …) 包着
但是既然那样那参数还有必要用 &body 吗?

因为你连 defmacro 是怎么用的都没搞懂。

CL-USER> (slynk-backend:arglist 'defmacro)
(CCL::NAME ARGLIST &BODY CCL::BODY)

(defmacro plus (x y)
  `(incf ,x)
  `(+ ,x ,y))

CL-USER> (macroexpand '(plus x y))
(+ X Y)
T
CL-USER> 

可能觉得 defmacro 本来就预料只执行/返回一行代码,如果要多行那就用 (progn …) 包着 但是既然那样那参数还有必要用 &body 吗?

我是不是发现了 ANSI Common Lisp 的 bug?

1 个赞

如果defun定义函数本来就只能返回最后一个值,要返回多值就只能用values,那&body还有必要吗 :thinking: :rofl:

可能也是因为我还没实战中用这个 once-only,第一感觉好像跟直觉有矛盾吧。。。