8

Let Over Lambda Chapter 3 セクション「不要なキャプチャ」には次のように書かれています。

「確かに、問題が発生しないように十分に珍しい名前を考えることができます。はい、多くの場合、パッケージとスマートな変数の命名により、変数キャプチャの問題を解決できます。ただし、最も深刻な変数キャプチャのバグは、コードで直接発生することはありません。ほとんどの変数キャプチャの問題は、他のマクロが予期しない方法でマクロを使用する (マクロと組み合わせる) 場合にのみ表面化します。 "

そして、太字部分の例を教えてくれません。そのような例の一つは何でしょうか? 架空の Lisp 開発チームを想像してみてください。狂ったボスが gensym や、インターンされていないシンボルを作成するあらゆるものの使用を禁止し、プログラマーは gensym を逃すたびに temp-27s63f8sk2n や sum-3t84hj4df のような確率変数名を思いつくために英数字のサイコロを投げることに頼っています。チームがトラブルに巻き込まれる例は何ですか?

そういえば、Emacs 24.3.1 では、インターンされていないシンボルを使用せずに dotimes と dolist を定義しています。変。

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 に答える