8

放弃 Lambda 第 3 章“不需要的捕获”部分说:

“当然我们可以想出足够稀有的名字,这样问题就永远不会出现。是的,在很多情况下,包和智能变量命名可以解决变量捕获的问题。但是,大多数严重的变量捕获错误不会直接出现在代码中“ _ _

然后它没有给我一个粗体部分的例子。这样的例子之一是什么?想象一个假想的 Lisp 开发团队,其疯狂的老板禁止使用 gensym 或任何会创建 uninterned 符号的东西,而程序员只要在错过 gensym 时就简单地投掷字母数字骰子来想出诸如 temp-27s63f8sk2n 或 sum-3t84hj4df 之类的随机变量名称。什么是团队会遇到麻烦的例子?

说到这一点,Emacs 24.3.1 定义了 dotimes 和 dolist 而不使用 uninterned 符号。诡异的。

4

2 回答 2

2

好的,那么我建议自动化“投掷字母数字骰子”的过程。当然,它不一定是随机的,你可以使用一个计数器。此外,如果能够指定前缀以进行调试,那就太好了。哦,等等,这正是gensym它的作用。

于 2013-07-03T07:57:19.577 回答
1

当您在其他上下文中重新使用自己的宏并且您巧妙的命名空间变量实际上是多余的时,就会出现问题,因为它们都在同一个命名空间上。

我可以想到一个例子,当使用一个闭包访问一个封闭的变量时(let),它被传递给一个宏,该宏也使用一个封闭的(let)定义一个名称冲突的“安全”变量。这是一个人为的例子,对不起,我现在想不出一个真实的案例。

(defmacro my/a (x)
  (let ((my/safe-name x))
    `(progn ,(my/b (lambda () my/safe-name))
            ,my/safe-name)))

(defmacro my/b (f)
  `(let ((my/safe-name 4))
     (when (evenp (funcall ,f))
       (print "F is even!"))))

(my/a 3) ; will print "F is even", but it shouldn't
于 2013-07-02T23:49:27.127 回答