[SML 7312] ブロック生成のメタプログラミング
AOKI Atsushi
aoki @ sra.co.jp
2007年 9月 6日 (木) 10:12:09 JST
SRA先端技術研究所の青木です。
じゅんメーリングリストの話題をSMLにも流すことにしました。
ブロック生成の例として、シンボルが asBlock / asBlockFor: の
メッセージを理解できるようにするプログラムを添付します。。
似たようなプログラムがちらほらと存在するのですが、どれもベタ
なプログラムでエレガントさに欠けますので、ユニバーサル・メッ
セージ(万能関数)を用いたメタプログラミング(高階関数)手法
で実装しておきました。
#VisualWorks のプログラムですが、Squeak でも動作することを
#西原さんが確かめてくれています。
伝言選択子(メッセージ・セレクタ)シンボルに対して用いるのが
適切です。使い方は以下のようになります。
#size asBlock
#@ asBlock
#x:y: asBlock
#x:y: asBlockFor: Point
どんなブロックが生成されているのかは、逆コンパイルをしてみれ
ば判明します。
#size asBlock method decompiledSource
==> '
[:t1 |
| t2 |
t2 := Array new: 0.
t1 perform: #size withArguments: t2]'
#@ asBlock method decompiledSource
==> '
[:t1 :t2 |
| t3 |
(t3 := Array new: 1) at: 1 put: t2.
t1 perform: #@ withArguments: t3]'
#x:y: asBlock method decompiledSource
==> '
[:t1 :t2 :t3 |
| t4 |
(t4 := Array new: 2) at: 1 put: t2.
t4 at: 2 put: t3.
t1 perform: #x:y: withArguments: t4]'
(#x:y: asBlockFor: Point) method decompiledSource
==> '
[:t1 :t2 |
| t3 |
(t3 := Array new: 2) at: 1 put: t1.
t3 at: 2 put: t2.
self perform: #x:y: withArguments: t3]'
伝言選択子としてのシンボルがブロックになる効用は、次のような
典型的な場合が考えられます。
(0 to: 9) select: #even asBlock
==> #(0 2 4 6 8)
(0 to: 9) reject: #even asBlock
==> #(1 3 5 7 9)
(0 to: 9) collect: #even asBlock
==> #(true false true false true false true false true false)
#('asaoka' 'aoki') collect: #size asBlock
==> #(6 4)
#(0 2 4 6 8) with: #(1 3 5 7 9) collect: #@ asBlock
==> #(0 @ 1 2 @ 3 4 @ 5 6 @ 7 8 @ 9)
#(0 2 4 6 8) with: #(1 3 5 7 9) collect: (#x:y: asBlockFor: Point)
==> #(0 @ 1 2 @ 3 4 @ 5 6 @ 7 8 @ 9)
#(0 2 4 6 8) fold: #+ asBlock
==> 20
#(1 3 5 7 9) fold: #* asBlock
==> 945
#(12 21 -19) inject: 9999 into: #min: asBlock
==> -19
#(12 21 -19) inject: -9999 into: #max: asBlock
==> 21
今、ある人たちと協力して、この機構を VisualWorks の新バージョ
ンに導入しよう、というロビー活動をしてます。ぜひ Squeak でも。
asBlock / asBlockFor: のメッセージに応えられる他のオブジェク
トの候補としては Message / MessageSend / BlockClosure などの
オブジェクトたちがあげられると思います。
Smalltalk はメタプログラミングが気軽に(あまりにあっけなく)
できるので、プログラマに備わっているファンタジー創世の能力が
刺激され、増幅されることがしばしばでしょう。
また、メタプログラミングはスーパープログラマへの道です。自己
相似の中に入ってフラクタルな次元に遊ぶ、という感じになります。
このように言及しても、成長段階にあるプログラマには通じないで
しょうから、C プログラミングの状況で、誤解を恐れずに翻訳する
と、おおよそ以下のようになると思います。
今、ここに「test.c」というプログラムがあったとします。この実
行可能プログラム「test」が走行している真っ只中でやっているこ
とは、走行状況に応じて「subs.c」というソースコードを創り出し、
それをコンパイル&リンクするための「Makefile」も創り出してお
いて「make」を起動(fork:dup&exec&wait)させ、「subs」という
実行可能プログラムを獲得します。そして最後に「subs」を起動し、
その実行結果をもらって、「test」が走行し続けるというものです。
もちろん「subs.c」や「Makefile」そして「subs」などは跡形も無
く(unlink)しておくのは当然のこと。
------------------------------------------------------------
R2D2 (AOKI Atsushi) http://www.sra.co.jp/people/aoki/
-------------- next part --------------
テキスト形式以外の添付ファイルを保管しました...
ファイル名: asBlock.st
型: text/xml
サイズ: 2898 バイト
説明: 無し
URL: http://www.akademia.co.jp/pipermail/sml/attachments/20070906/1334c6eb/asBlock.bin
SML メーリングリストの案内