Daysこの広告は、90日以上更新していないブログに表示しています。)はじめに今回のネタはtools.macroです。tools.macroは,ライブラリのREADMEによれば「マクロを書くためのツール」という位置づけで,現在提供している主要な機能はmacroletとsymbol-macroletです。Lispの同名の特殊形式と同じように,それぞれローカルマクロとシンボルマクロを定義するのに使うことができます。Clojureは,(少なくとも現時点では)ローカルマクロやシンボルマクロを言語としてサポートしていないため,そういった機能が必要な複雑なマクロを定義する場合等にはtools.macroのマクロを使うのが便利です。インストール2013年12月現在のtools.macroの最新版は0.1.2です。tools.macroをインストールするには,Leiningenを使用している場合はproject.cljの:dependenciesに以下を追加します。"0.1.2"]使い方macroletはletfnと同じ形式でローカルマクロを定義します。1)))))これは以下と等価です。1))))symbol-macroletはletと同じ形式でシンボルマクロを定義します。x)))これは以下のように展開されます。x))この展開結果を見ても分かるように,macroletやsymbol-macroletはマクロと同名のシンボルが出現する箇所を盲目的に置き換えるのではなく,Clojureの構文を理解してマクロの展開が可能な位置を認識します。コードウォークが必要なマクロを定義する場合は,この観点から,むやみにclojure.waok/postwalkなどの関数を使うのではなく,macroletやsymbol-macroletを使う方が安全です。Lambdaに登場するパンドリックマクロを実装してみます。macros)とは,クロージャが捕捉しているローカルな環境に,その環境の外側から(見かけ上)アクセスできるようにするマクロです。本来,外側からはアクセスできないはずのローカル環境に無理矢理アクセスする禁忌を,「パンドラの箱」を開けることになぞらえてこの名前がつけられています。外側からローカル環境にアクセス可能なクロージャを作るためにはpfnマクロを使います。2)84user=>pfnの第1引数は通常の引数リストです。第2引数には外からアクセス可能にする変数を指定します。上の例ではクロージャが捕捉するローカル変数xをアクセスできるようにしています。pfnで生成されたクロージャはもちろん通常のクロージャと同じように関数適用できます。pfnでアクセス可能にした変数の値を取得するにはwith-pandoricマクロを使います。with-pandoricマクロの第1引数では,pfnで作ったクロージャでアクセス可能にした変数のうち,with-pandoricのボディで実際にアクセスする変数を指定します。第2引数にはpfnで作ったクロージャを渡します。上の例では,fで捕捉された変数xの値42がwith-pandoric内で取得できています。実装このようなマクロpfnおよびwith-pandoricをシンボルマクロを使って作ってみましょう。~@body))))パンドリックマクロの使用例pfnとwith-pandoricを使って,リセット可能なカウンタを作ってみましょう。@x)))これを以下のように使います。おわりに今回はtools.macroが提供するmacroletとsymbol-macroletを紹介しました。Lambdaのパンドリックマクロを実装しました。ここではmacroletの実用例については詳しく見ていませんが,(手前味噌ですが)たとえば以下のようなマクロが参考になるかもしれません。4はてなブログをはじめよう!athosさんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。