Java には何でないのだろう?
2008.03.18
というのは、マクロの話です。
私は Eclipse 使いじゃない(由緒正しく Emacs でコーディングする人)ので、たとえば JavaBeans のアクセサを、Emacs のキーボードマクロで変数宣言から自動生成するなんてしています。まこれは勿論 Eclipse 使いの人だったら、そういう自動生成を使っちゃっているのでは?とも思いますが、逆にこういうの、
手で生成して間違いがあった時にめちゃくちゃうっとおしい
ので、是が非でも「自動生成」すべきものです。OK? で...そういう時に、
マクロがあればねえ...
と思ったことのある人は多いのでは、と思います。まあ、強引にそういうマクロを、アノテーション+JavaAssist(みたいなクラスファイルを直接書き換えるようなタイプのバイトコード・エンジニアリング・ライブラリ)で、事後的に JavaBeans のアクセサを生成する、というのは出来なくもない(private なフィールドだとラッパクラスで包んでやれない...あるいは、ラッパを作るのならばリフレクションでprivate を一時的に解除する)のですが、やたらと手がかかります。でしたら、逆に
Java World ですべてを完結させずに、適当なテキストフィルタで置換した方がずっと早い....
なんて思ったりしちゃう(思うだけではなくて実行も...)わけです。
まあ、アノテーションを使った XML(とかでの) データの自動生成も使えないわけではないですが、意外にアノテーション・プロセッサの処理は面倒だったりします。「ちょいとしたマクロ代わり」というような不純な動機で使おう...というのにはさすがに敷居が高いですね。
Java にマクロがない理由、っていうと、やっぱりこんなことが嫌われたのでしょうか...
- 1. Java のソースはいわゆる「前方参照性」が問題にならない、という前提をマクロは崩す。もちょっと易しい言い方をすると、ソースコードの後の方にあるインスタンス変数やメソッドを、ソースコードで宣言が登場する以前に、前のほうで参照しても問題がない(変数・メソッドの「宣言順」はどうであっても問題にならない)...というのが Java のイイところの一つですが、マクロは define, undef とかあるように、「今のマクロの内容如何」によって、展開されるコードが変わりうるわけです。「マクロ定義の登場順」に依存した生成コードになっちゃうんですね(もちろんそれでエラーになる可能性も...)。これは原理的に違う...と思われたのかなぁ。
- 2. マクロは「大域置換」であって、特定のクラスに所属する...とは言えない。Java では変数だろうとメソッドだろうと何でもかんでも、クラスに付属していますね。ですけど、マクロの置換指示はとくに「このクラスだから....」という感じではなくて、マクロを実行するならば、たとえばマクロ定義をした static クラス MyMacroDefines を implements して置換指示をするような格好になるのでは?などとも思います。ここらへんもイレギュラーですね。
まあ、こんなことを考えちゃったりするのは、最近の関数型言語でもマクロが健在だ、というあたりからです。たとえば Erlang でもC言語風のマクロがありますし、Lisp→Scheme→Gauche だったら昔ながらの強烈なマクロがずっと存在しているわけです(Paul Graham の「On Lisp」(本だと)で使い倒してますね...)。また Gauche だと、R5RS(Schemeの仕様)で定義された「健全なマクロ」と二本立てだったりするわけです(単純に「健全」を言い換えると、「変数のバッティングが起きない」ということくらいにご理解ください)。ま、Lisp のマクロはCのマクロとはレベルの違う「プログラムジェネレータ」みたいなものですから、「Lispマクロ」として研究する価値のあるものです....
マクロ、というとマイナーながら m4 みたいなスタンドアロンのマクロプロセッサも UNIX なら必ずありますし、そろそろ天寿を全うし...に近くなっている(失礼) TeX が典型的なマクロ言語でしたから、「マクロの世界」というのは実はかなり深い歴史と実績がある「別な世界」だったりするのです。
さすがに Haskell にはマクロはないようです....ま、これは当然か。
投稿者 : 杉浦 こずえ | 投稿日時 : 2008.03.18 16:43
あすなろBLOGのトラックバック・コメントは承認制になっています。
すぐにブログに反映されませんので、ご了承ください。





