ClosureCompiler
これまで、クロージャで遊びたいときには Squeak では駄目*1なので、Strongtalk *2 や VisualWorks*3 を使っていた*4のですが、この ClosureCompiler を使えば、その必要はなくなりそうです。インストールにちょっとコツがいるのでメモしておきます。ポイントは、いったん古いバージョンをインストールしてから、SqueakMap 経由で上書きすること。 試したのは、現在入手可能な最新の開発途上バージョンの Squeak3.8g-6548 (.zip, 8.7Mb。他に Squeak VM、SqueakV3.sources、各種プラグインなどは別途入手の要あり) 。Squeak3.7 でも、すくなくともブロッククロージャを使うことはできるみたい*5です。
- ClosureCompiler2-ajh.zip を入手して Squeak3.8 のフォルダ内に展開
- Squeak を起動
- open... -> file list でファイルリストを起動
- ./ClosureCompiler2-ajh/README.txt を開き、そこに書かれた手順1〜3を行なう
- SqueakMap に戻って、Compiler をインストール
(ダイアログポップアップには Yes ) - 引き続き、ClosureCompiler をインストール
ブロックをクロージャ(a BlockClosure)として使いたいときは、help.../appearance... -> preferences... -> general -> #compileBlocksAsClosures を on 。普段(eToys するときなど)は off 。
ブロックがクロージャになっているときは、次のようにブロックを再帰させるようなスクリプトも評価して値を得る( print it (alt-/cmd-p) )ことができます。
fact |
=> 3628800
前に触れた、プライオリティの異なるマルチスレッドを記述する際の、ブロック変数がらみの問題も起こりません。
stream forGoingOn defaultPriority putSemaphore |
#compileBlocksAsClosures が on(ブロックが a BlockClosure)のとき。
=> '1a2b3c'
#compileBlocksAsClosures が off(ブロックが a BlockContext)のとき。
=> '112233'
あと、この拡張によりなぜかブロック変数が擬変数でなくなる(代入できるようになる)ので、技術野郎の復讐のアキュムレータの例では、おそらく最も短く、比較的簡潔に書くことができる言語のひとつとなります。w
FOO_[:n|[:i|n_n+i]]
ちなみに Common Lisp では(同じく詰めて書いた場合でも)これが精一杯(^_^;)。
(defun foo(n)#'(lambda(i)(incf n i)))
使用例:
foo |
=> 101 102 103 104 105 106 107 108 109 110
まあ、定義は短くても、いざ使うときには冗長になるので、やっぱり負けは負けなんですが……
(続く)
*1:Squeak は、XEROX Smalltalk-80 の流れこそ汲んでいるのですが、非常に古いバージョンを基に作られたため、90 年代に生まれた比較的新しい Smalltalk であるにもかかわらず、80 年代当時の古典的仕様や、その後の進化の過程で他の Smalltalk 処理系が手放してしまった特徴を、いまだにいくつか残しています。ブロックがクロージャになっていないことも、そうした“先祖返り”的側面の一つです。
*2:オプショナルながら静的型チェックが使える、クラスでなくミックスインベースの“変わり種”Smalltalk。Java も関係する VM 高速化技術がらみにおいても、知る人ぞ知る無視できない存在。
*3:由緒正しい XEROX/ParcPlace Systems Smalltalk-80 の流れを汲む、純正 かつ 近代的 かつ 最新 の Smalltalk 処理系。現在は Cincom が開発/販売。 駄目ですよ。 Smalltalk-80 が滅びたとか、開発が止っているとかいうデマを信じちゃ…。w
*4:他に、私の手元の環境では動かせないのですが、ANSI 準拠の GNU Smalltalk など、とにかく Squeak のように異常に古い処理系でなければ、たいていブロックはクロージャになっているはずです。あと、余談ですが、smalltalk.org や GNU Smalltalk が本家というのはデマです。念のため。
*5:なにしろコンパイラの仕様をもいじる大がかりな拡張なので、他の部分との整合性がどうなっているのか、私のような素人にはさっぱりなものでして…。