2011/09/16

今さらながらブログはじめました。

こんにちは、@tomoodaです。

今まで書きたいことは基本的にtwitterに書いていましたが、やっぱり文字数制限がつらい。ツ コード例とか書くだけでももう大変。それがブログなら

(PGeneGenerator
    on: [ :g | 
        | i j |
        i := 0.
        g yield: i.
        j := 1.
        g yield: j.
        [ 
        i + j
            =>> [ :k | 
                g yield: k.
                i := j.
                j := k ] ] repeat ])
    =>> [ :fibonacci | 
        10
            timesRepeat: [ 
                Transcript
                    cr;
                    show: fibonacci next printString ] ]

がはははは、余裕で書き下せるぜい!勝ったも同然。なお、上記のコードはPharoというSmalltalk処理系でフィボナッチ数列を10個、トランスクリプトウィンドウに表示します。

Smalltalkerにも見慣れないモノがあると思いますが、これは開発中のPGeneというライブラリが実装するジェネレータPGeneGeneratorの例題です。Pythonのジェネレータがあまりにも便利なので、ついSmalltalk上で実装しちゃいました。

Smalltalkには昔からStreamクラスがあり、nextメッセージを投げる毎に次の値を返してくるのですが、いかんせん数列を定義する度にクラスを定義したのでは、「だからクラスベースは…」などと言われてしまいます。

また、Smalltalkには昔からdo:メッセージもあり、クロージャを渡して繰り返し評価をします。しかし悲しいかな、do:はファーストクラスオブジェクトではないのです。複数のオブジェクトから次から次へとnextメッセージを投げるような自由度はありません。

そこでジェネレータです。nextメッセージを受け取ったら、クロージャ[:g | ... ]を評価します。そして、クロージャを評価していく中で、使いたい値が手に入ったらいつでもyield:メッセージを投げれば、その引数がnextメッセージの返り値となります。また、次にnextメッセージを受け取ったら、前回yield:した箇所から実行を再開して、次のyield:がnextの返り値になります。まあ、なんて便利なんでしょう。ツ このように2つの実行コンテキストを交互に継続させることをコルーチンといいます。

Smalltalkは実行コンテキストまでファーストクラスオブジェクトなので、この程度のことはフフンのフンなのです。ツ

次に見慣れない表記は=>>でしょう。一般には、expr =>> [ :name | ... ]という形で使って、exprの評価結果にnameという名前をつけて、...を評価します。これがあると何が嬉しいかと言うと、自然とローカルなスコープになるだけでなく、破壊代入と名前束縛を明示的に分離できるのが最大の利点です。Smalltalkは関数型言語でも論理型言語でもないので、破壊代入は悪ではありません。しかし、濫用せずに、弊害を最小化しながらそのメリットを享受しようじゃないですか。ツ ちなみに、実装としては=>>の左側のオブジェクトを引数にして右側のクロージャを評価しているだけです。

こんな調子で、Smalltalkのこと、オブジェクト指向のこと、プログラミングのこと、その他いろいろ書いていきます。
よろしく! ツ

0 件のコメント:

コメントを投稿