マクロ衛生とは?
まくろえいせい
マクロ衛生とは、マクロが展開された際に呼び出し元のスコープにある変数名と意図せず衝突しないよう、マクロ内の識別子を安全に隔離する性質です。
マクロ衛生(Hygienic Macros)は、プログラミング言語のマクロシステムが持つ安全性の性質で、マクロが展開されてもマクロ定義内の変数名と呼び出し側の変数名が互いに干渉しないことを保証します。
問題の背景を理解するために、まずCプリプロセッサのような「非衛生的なマクロ」を考えます。例えばスワップマクロ SWAP(a, b) を内部で一時変数 tmp を使って実装した場合、呼び出し元に tmp という変数が既にあると、展開後にそちらと衝突してバグが生じます。このような名前の衝突は静的に見つけにくく、デバッグが困難です。
衛生的マクロはこの問題を以下のような方法で解決します。
- スコープ情報の付加:マクロ内の識別子にマクロ定義時のスコープを記録し、展開後もそのスコープで解決する
- 名前の自動リネーム:コンパイラがマクロ内の束縛変数を一意な名前に自動変換して衝突を回避する
衛生的マクロを採用した代表的な言語・システムには次があります。
- Scheme(R5RS以降):syntax-rules や syntax-case
- Rust:macro_rules! マクロはデフォルトで衛生的
- Elixir・Clojure:それぞれ独自の衛生的マクロ機構を持つ
一方でCプリプロセッサやLisp初期のdefmacroは非衛生的であり、プログラマが自分で衝突を回避する責任を負います。マクロ衛生はメタプログラミングを安全に行うための重要な設計要素です。
使い方・例文
Rustのmacro_rules!で定義したマクロは衛生的であり、マクロ内で使う一時変数が呼び出し元の同名変数を誤って上書きするという古典的なバグが防止されています。
この用語をシェア
最終更新: