« 連載: Smalltalk use: better《11》はやくオブジェクトになりたいっ | トップページ | 連載: Smalltalk use: better《13》true/false が Boolean だったら »

2006年5月23日 (火)

【準備中】連載: Smalltalk use: better《12》はやくメッセージになりたいっ

キーワード ◆ Smap・コンパイラー・ブロック・ブロック引数・メッセージ式・一時変数・演算子 ?:・回文・階乗・制御構造

※ PDF でご覧になるなら ⇒ 公開日まで、しばらくお待ちください。

------------ 序 ------------

臨死のマック抱く妻の心理
りんしのまつくだくつまのしんり

「またたび浴びたタマ」村上春樹

◆ 回文というのは、逆から読んでも成立する文を表します。よく知られた例文には「竹屋が焼けた」というのがあります。英文には "Madam, I'm Adam." というのもあります。他にも「ビキニの下は私のニキビ」というのが…。

◆ フランス大会(1998年)のときに創作したものです。回文に、解説が必要ということ自体、出来が良くないことの証ですが…。これを機に成仏させるべく、恥を忍んでここに残しておきます。

力士「え〜!この二枚はレヤ…」ジダン「駄洒落は、いまに!」の声しきり。

りきしえこのにまいはれやじだんだじやれはいまにのこえしきり

【解説】力士だって人の子。本場所を抜け出しても、ワールドカップを見に行きたぁ〜い。タニマチから、二枚のレヤものプラチナチケットをゲ〜ット。金星と同伴で、意気揚々とチャンコ屋へ繰り出します。そこで、何気にテレビを見ていると、フランス代表のジダン選手を起用したコマーシャルが…。しかし、彼が口にした駄洒落は、いまいちというか、いまにというか…。彼のプレーは超一流なだけに、ちょっと拍子抜けがする思いなのでした。

------------ 本文 ------------ 

◆ Smalltalk には、コンパイラーに組み込みの制御構造はありません。つまり、制御構造も、メッセージ式を使って表現するのです。

| min |
min := [:a :b | a < b ifTrue: [a] ifFalse: [b]].
min value: 3 value: 4.          "3" 
min value: 5 value: 4.          "4"   

60523a ◆ 最小値を求めるブロック min を用意します。これにメッセージ value: 3 value: 4 を送ると、2つの引数の最小値 3 が得られます。ブロック内に記述された次のメッセージ式は、

a < b ifTrue: [a] ifFalse: [b]


Java で記述されたコードの断片を彷彿とさせます。

a < b ? a : b

キーワードセレクター ifTrue:ifFalse: の引数には、それぞれブロック式を指定します。ここで`ブロック式`と表現したのは、リテラルだけでなく、変数、およびメッセージ式を評価したときにブロックが得られるものを、引数として指定できることを意味します。

◆ 再び、ブロック内に記述されたメッセージ式に着目してください。このとき、ifTrue:ifFalse: を伴うメッセージを受け取る相手は何でしょうか。二項セレクターの方が優先順位が高いので、先に a < b が評価されます。すると、このメッセージ式を評価したときに得られるオブジェクトに対して、メッセージ ifTrue: [a] ifFalse: [b] が送られるものと期待されます。

a < b ifTrue: [a] ifFalse: [b]

60523b ◆ オブジェクト a にメッセージ < b を送ると、オブジェクト true または false が得られます。これに、メッセージ ifTrue: [a] ifFalse: [b] を送ると、オブジェクト a または b が得られます。

| factorial |
factorial := [:n | | m |
    n < 0 ifTrue:[m := n negated] ifFalse: [m := n].
    m factorial].
factorial value: 3.          "6"
factorial value: 0.          "1"
factorial value: -3.          "6"

◆ 階乗を求めるブロック factorial を用意します。これにメッセージ value: -3 を送ると、負号を取り除いた数 3 の階乗である 6 が得られます。その定義により、0 の階乗は 1 となるので、注意が必要です。負数の階乗は未定義なので、この事例は、ifTrue:ifFalse: を説明するための便宜的なものと考えてください。

◆ ブロック内だけで有効な一時変数を宣言するには、| と | との間に、識別子 m を記述します。ブロック引数 :n に続く | は、その宣言部とブロック本体に記述するメッセージ式との区切りを表します。最初は奇異な感じがするかもしれませんが、これも慣れの問題で、それまでは少し注意が必要です。

| factorial |
factorial := [:n | | m |
    m := n < 0 ifTrue:[n negated] ifFalse: [n].
    m factorial].

◆ ifTrue:ifFalse: を使うときには、ブロック式を評価して得られるオブジェクトを、そのまま変数に代入できます。そのため、ブロック内で個別に変数 m に代入するのではなく、ifTrue:ifFalse: を伴うメッセージ式を評価して得られるオブジェクトを変数 m に代入すると、より簡潔なコードを記述できます。これは、Java で記述された、次のコードの断片を彷彿とさせます。

m = n < 0 ? -n : n

【課題】負数の階乗
負数の階乗を、その絶対値の階乗に負号を付加したものとする、別の factorial を定義してください。

【補足】

| min |
min := [:a :b | a < b ifTrue: [a] ifFalse: [b]].
min value: 3 value: 4.          "3"

60523c_1 ブロック内外に記述されたコードを展開した形で表現すると、その Smap はこのようになります。

【補足】次のメッセージ式は、

min value: 3 value: 4
factorial value: 3

Java 擬で表現すると、次のようになります。

min.(3,4)
factorial.(3)

==================================
真樹育未 著 ◆ 監修:小泉ひよ子とタマゴ倶楽部

|

« 連載: Smalltalk use: better《11》はやくオブジェクトになりたいっ | トップページ | 連載: Smalltalk use: better《13》true/false が Boolean だったら »

Squeak/Smalltalk」カテゴリの記事

.連載: Smalltalk use: better」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: 【準備中】連載: Smalltalk use: better《12》はやくメッセージになりたいっ:

« 連載: Smalltalk use: better《11》はやくオブジェクトになりたいっ | トップページ | 連載: Smalltalk use: better《13》true/false が Boolean だったら »