サーチ…
シンタックスルールを備えた衛生的かつ参照透過的なマクロ
LISPとSchemeの最大の利点は、他の主流のプログラミング言語よりマクロシステムです。 Cプリプロセッサや他のマクロ言語とは異なり、Schemeマクロは解析されたコードを入力として受け取り、展開されたコードを出力として返します。これは、Schemeの "code is data"というフレーズのアプリケーションの1つで、言語を非常に強力にするものです。
Schemeのマクロは、 define-syntaxで作成され、さまざまな方法でマクロを定義できます。最も簡単な方法は、パターンマッチングを使用して入力コードを出力コードに変換するsyntax-rulesを使用することです。
この例では、 for item in list内の要素を単純for item in list作成し、リスト内の要素をループするためのfor list as item構文for list as item for item in list作成します。
(define-syntax for
(syntax-rules (in as) ; 'in' and 'as' keywords must match in the pattern
; When the 'for' macro is called, try matching this pattern
((for element in list
body ...) ; Match one or more body expressions
; Transform the input code
(for-each (lambda (element)
body ...)
list))
; Try matching another pattern if the first fails
((for list as element
body ...)
; Use the existing macro for the transform
(for element in list
body ...))))
これらの2つのマクロは、次のように使用することができます。
(let ((names '(Alice Bob Eve)))
(for name in names
(display "Hello ")
(display name)
(newline))
(for names as name
(display "name: ")
(display name)
(newline)))
コードを実行すると、予想される出力が得られます。
Hello Alice
Hello Bob
Hello Eve
name: Alice
name: Bob
name: Eve
注意する最も一般的な間違いは、正しい値をマクロに渡していないため、マクロ呼び出しではなく展開されたフォームに適用されるエラーメッセージが間違ってくることがよくあります。
上記のfor構文定義では、識別子とリストが渡されているかどうかをチェックしないので、他の型を渡すと、 for-each呼び出しの代わりにfor-each呼び出しfor-each指すエラーforます。これをデバッグすることはマクロの目的に反するため、そこに小切手を入れ、使用時のエラーを報告するのはユーザーの責任です。このエラーはコンパイル時に捕まえることができます。
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow