Rubyいいね。イテレータがいい。とはいえこれ、オブジェクト指向を 徹底しているからいい、というもんではない。結局全ての構文が「式」である ことを徹底しているから具合がいいのだ。それはLispと一緒。Lispでは 制御構文も式である。
答えがyesならx=1に、そうでなければx=0に設定する。こんなときアセンブラ であるCではこう書く。
if (!stricmp(ans, "yes")) { x=1; } else { x=0; }
ifとか、制御構造は制御構造であって式ではない。Javaだってそうだ。 Lispだと、制御構造は実は式の一種。根がC屋なLisp初心者は最初
(if (string-equal ans "yes") (setq x 1) (setq x 0))
と書くが、Lispの全てが「式」であることを理解したLisperは、
(setq x (if (string-equal ans "yes" 1 0)))
と書く。式の値の大切さに目覚めた人はCにおいても
x = (!stricmp(ans, "yes") ? 1 : 0);
が簡潔であると気づく。が、C言語家族が簡潔なのはここまで。 値が三分岐になるともうわけわかんない。だから条件演算子は一個ネストしただ けでたちどころに読みづらくなって、嫌われる。
で、Rubyに戻る。Rubyも全てが式という姿勢を貫いている。制御構文、これ また式である。
x = if (/yes/ =~ ans) then 1 else 0 end;
てことでif構文全体が値を持つ。Lispのcondがそうであるように、 Rubyのcase構文も一個の値を持つ。これ、小さな違いだが、これをちゃんと利用 するとかなりプログラムがきれいに書ける。制御構造の全ての分岐の文脈を 自然に揃えることができる。
で、Rubyのイテレータ。これもいい。何でいいかっていうとこれ、 LispのmapcarのあらゆるEnumerableへの拡張版だからだね。mapcarをうまく使う ためには、関数のリテラル、つまりlambda形式が必須になるのでRubyでも ちゃんとイテレータに与えるブロックはlambda関数の役割。えらすぎ。 Proc.newのalias として lambda なんてのが使えるのも泣ける。
PascalおよびC家系の顔をしたLispだね。S式の形式でプログラムを 書くことと、コンスセルとリストの構造の理解を強要しないLispがあったら そりゃ飛びついていいんでないかい? それがRubyだと思った。と、とりあえず Rubyのプログラム一個も書いてない時点で思ってみた。あとで読み返して 笑う日を待つ。
買物した。税込み888円。いいことあるかな?