言語実装の続き

晴。

Ruby で遅延評価 · GitHub
Haskell-like な言語の実装の続き。Inspect などを実装。あとは細かいリファクタリング。ひとまず落ち着いた感じか。ひさしぶりに他の何もかもを忘れてプログラミングに熱中したな。下は Inspect(ないしは Reduce, Foldl) と Reverse の実装例。

Inspect = Lambda!(3) {|f, acc, list|
  if list.ev.instance_of?(Cons)
    x, xs = Car * list, Cdr * list
    Inspect + f  + f * acc * x + xs
  else
    acc
  end
}

Reverse = Inspect * Lambda2 {|acc, x| x >> acc} * Null

 
夕方、窓拭きを手伝う。


言語実装の続き。無限遅延ストリームを使ってフィボナッチ数列を求める例。

fib = Lambda2 {|a, b| a >> fib + b + Add * a * b}
fibs = fib * 0.thunk * 1.thunk

evaluate Print + Take * 10.thunk * fibs
#=>[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Ruby でふつうに同等のコードとなると、Enumerator を使って次のようになるか。

fib = Enumerator.new do |y|
  a, b = 0, 1
  loop do
    y << a
    a, b = b, a + b
  end
end
p fib.take(10)
#=>[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Ruby は簡潔に書ける言語だけれども、ここでは Ruby の方が行数を使っているのがおもしろい。
その他、細かいところを直したり、ちょっとした汎用関数を実装したり。


『禅海一瀾講話』を読んで寝る。