K2NR.ME

このエントリーをはてなブックマークに追加 Tweet

麗らかなRubyタレントと遅延評価〜if関数の実現について〜

なんつータイトルだ。

なんか無駄に感動したので執筆途中のClojure連載を放置してこっちを記事にします。事の発端はこれ→池澤あやかのプロフィール

う、美しい・・・。これが新人類ってやつか。 「Ruby始めたら彼女ができました!」だの、「Ruby始めたら腰痛が治りました!」だの、にわかには信じがたいRubyのスーパーパワーがまことしやかに囁かれる昨今ですが、あながち全てがウソとも言い切れないのかもしれません。

プログラマタレントとして新ジャンルを開拓するつもりなのか、それともプロのプログラマとしての人生を歩むのか、彼女の今後の人生が非常に気になる所ではありますが、今日記事にしたいのはそんなことではありません。

口癖:うわあ…

こんな上から目線のセリフ言われてぇ。。。

という話、では、なく、て。

好きな関数:if

こっちです。Ruby女子と高らかに宣言しておきながら好きな関数がifというのは解せぬ。Rubyistではない僕でもRubyにおいてifが関数ではなく制御構文であることは知っています。どういうことなのか。Rubyの話ではないということでしょうか。確かに「好きなRubyの関数」などとはどこにも書かれていません。

それでは、ifを関数として実装している言語とはなんでしょう。少し調べましたが僕の知る限りでは存在しないようです。謎は深まるばかりなのでここで少し視点を変えてみましょう。

「好きな関数は?」と僕が聞かれれば、おそらく自作した関数のうちどれかを選びます。人が作ったものよりも自分が作ったものに愛着が湧くのは当然のことです。つまり、彼女もそういうことなのではないかと。自分が作ったif関数が一番好き、という意味なのではないかと。その関数をifと呼ぶ以上、その自作関数を作成した言語における本物のifと全く同等の振る舞いを行う関数であることが推察されます。

それでは彼女は、Rubyでif関数を自作したのでしょうか?それは不可能です。Rubyのifというのは

if test then
    state1
    state2
    ...
else
    state3
    state4
    ...
end

こんな形をしていて、そもそも「関数」として扱うことは難しい構造です。ifを関数として扱うためにはまず第一にthenとelseの中身が複数ステートメントによるコードブロックではなく単一の式である(つまり、引数としてif関数に渡せる)必要があります。そして第二に、こちらのほうが重要ですが、言語レベルで遅延評価を実装していることが求められます。

遅延評価が必要とはどういうことなのか。説明のためにSchemeというlispの方言を用いて自作ifを実装してみましょう。 (サンプルはまるまる、SICPのExercise 1.6から拝借しました)

(define (new-if predicate then-clause else-clause)
  (cond (predicate then-clause)
        (else else-clause)))

使ってみます。

(new-if (= 2 3) 0 5)
5

(new-if (= 1 1) 0 5)
0

動いてますね。でもダメなんです。試しにリストの末尾要素を求める次のコードを実行してみましょう。

(define (tail lst)
  (new-if (null? (cdr lst))
          (car lst)
          (tail (cdr lst))))

(tail '(1 2 3 4))

エラーが出てしまいますね。new-ififに変えたら正しく動きます。これが遅延評価が必要である理由です。デフォルト遅延評価ではないSchemeのような言語では、if関数呼び出しの前にthen-clauseもelse-clauseも評価されてしまいます。その結果、上記の例ではlst(4)のとき((null? (cdr lst))が真のとき)に本来評価不要であるはずのelseルートの再帰呼び出しを実行してしまったのです。

それでは、先のif関数実装のための条件を満たした言語の一例としてHaskellで実装してみましょう。

myif predicate then_clause else_clause = if predicate then then_clause else else_clause

このmyif関数は完璧に正しく動きます。なぜなら実行されない側(predicateがTrueならelseclause、Falseならthenclause)は評価されないからです。

まとめると、if関数を実装するために使用する言語は遅延評価をデフォルトとして実装している必要がありますが、Rubyはこの条件を満たしていません。Haskell等のデフォルト遅延評価である純粋関数型言語を使用すれば実現可能です。

もはや彼女がRubyではなく何らかの純粋関数型言語を好きであることは疑いようのない明白な事実です。なぜ彼女はRubyが好きな言語だとウソをついたのでしょうか。裏で闇のRubyistたちが暗躍しているとしか考えようがありません。おそらく関数型言語が好きだなどと本音を言えない状況下に置かれているのでしょう。彼女の無事を祈っております。

追伸:Rubyの勉強会に参加したら彼女に会えるのでしょうか。誰か教えてください。

comments powered by Disqus