询问(defun defun () 3)的执行结果及CppCon相关问题的技术问询
1. 代码
(defun defun () 3) 会执行什么操作? 这是一段 Common Lisp 代码,得先从 Lisp 里的 defun 说起——它原本是用来定义函数的标准宏。而这段代码干了一件相当"出格"的事:用 defun 定义了一个名为 defun 的函数,这个函数不接受任何参数,调用后直接返回数值 3。
这里的关键问题在于,Lisp 里的符号(比如 defun)在同一个作用域下只能有一个主绑定。原本 defun 是负责定义函数的宏,执行这段代码后,它会被替换成我们自己定义的这个无参函数。
带来的后果是毁灭性的:
- 之后你再想用
defun定义其他函数(比如(defun foo () 42)),完全不会起作用。因为现在defun是个函数,你这么写相当于给它传了三个参数(函数名foo、参数列表()、函数体42),但我们定义的defun根本不接受参数,直接会抛出"参数数量不匹配"的错误。 - 如果你直接调用
(defun)(不带任何参数),它会返回 3——这是这个新函数唯一能做的事。
2. Herb Sutter 提到的「defun defun 3」有什么问题?
Herb 在那场 CppCon 演讲里拿这个例子,是为了对比不同语言的设计哲学——有些语言(比如 Common Lisp)允许你修改核心语言构造,而 C++ 则刻意禁止这种操作。
首先得说明,「defun defun 3」是他对 Lisp 代码 (defun defun () 3) 的简化表述,本质就是我们第一个问题里说的那段代码。
它的核心问题在于:你把用来定义函数的核心工具给废掉了。defun 是 Lisp 里创建新函数的基础,当你把它重定义成一个只会返回 3 的函数后,整个语言的扩展能力就被破坏了——你再也没法用常规方式定义新函数,后续依赖 defun 的代码全都会失效。
Herb 举这个例子的目的,是想强调 C++ 的设计理念:它不允许你重定义核心关键字或内置操作,避免这种自我毁灭式的修改,从而保证语言行为的可预测性和稳定性。
内容的提问来源于 Stack Exchange,提问作者 sp2danny。




