Clojureに衛生的なマクロがないことから生じる実際的な問題は何ですか?


11

Clojureマクロは簡単に記述できますが、ラケットの衛生的なマクロほど信頼性が低いと聞きました。私の質問には2つの部分があります。

  1. gensym衛生マクロとどう違うのですか?
  2. ラケットマクロは、Clojureにはないものを何を提供しますか?(安全性、構成可能性など)

2
衛生的なマクロとは、拡張によって誤って識別子がキャプチャされないことが保証されているマクロです。偶発的な捕獲の一般的な問題は、衛生マクロの導入前のLispコミュニティ内でよく知られていました。マクロの作成者は、固有の識別子(gensymなど)を生成する言語機能を使用するか、問題を回避するために難読化された識別子を使用します。衛生的なマクロは、マクロエクスパンダー自体に統合されているキャプチャの問題に対するプログラムによる解決策です。 en.wikipedia.org/wiki/Hygienic_macro
ロバート・ハーヴェイ

3
[ラケットの]衛生的なマクロシステムはマクロの動作方法に関する深い知識を持っているため、マクロは環境に非常によく統合されています。滑らかな[ラケット] IDE機能。つまり、衛生は、変数キャプチャなどの単純なバグから保護するだけでなく、Common LISPには存在し得ないツールによってコードを正式に分析できるようにします。 randomhacks.net/2002/09/13/hygienic-macros
ロバート・ハーヴェイ

回答:


6

衛生的なマクロの利点は言語機能の1つではありませんgensym。適切なタイミングで適切なクォート/アンクォートを使用して、適切な衛生状態のマクロを作成できます。ただし、衛生的なマクロを使用すると、マクロの衛生状態が良好になります。その点では、型チェックに少し似ています。

衛生的なマクロにはツールの利点もあります。ほとんどの衛生的なマクロシステムは、マクロの動作とその方法を厳密に制御します(たとえば、Schemeで定義されたマクロsyntax-caseが展開されると、任意のコードを実行できません)。これにより、マクロを「理解」するプログラムを作成しやすくなり、追加のツールサポートを提供できます。

一方、非衛生的なマクロが役立つ場合があります。たとえば、特定の変数(たとえば照応マクロ)のバインドを実際にキャプチャしたい場合、衛生的なマクロしかないと運が悪いと思います。


2
gensymマクロが誤ってマクロユーザーをいじるのを防ぎますが、マクロユーザーがマクロをいじるのを防ぎません。たとえば、マクロユーザーは再定義ifなどを行うことができます。(質問無関係である「なぜ誰もがそれを行うだろう」これは、それが可能だということを示して、それが非衛生的マクロについての理由にトリッキーだ簡単な例である。)
フィル・

2
非衛生的なマクロは確かに便利です。Schemeについてはわかりませんが、Racketには多くの「衛生曲げ」操作があります。言語のマクロはデフォルトで衛生的です。彼らはあなたが衛生を破るときにあなたを非常に意識させます。
フィル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.