stream-cons

2008.7.14

SICPのストリームの定義がかっこよくてしびれました。

例えば引数に指定した数から始まる整数列を返す手続きはSICPだと:

(define integers-starting-from n
  (stream-cons n (integers-starting-from (+ n 1))))

これをAS3でやると多分こんな感じになる:

function integersStartingFrom(n:uint):Stream {
  return new Stream(n, function():Stream {
    return integersStartingFrom(n + 1);
  });
}

自分が以前似たようなことをやったときは、同様の関数が以下のような醜い姿に:

function count(start:uint):Iterable {
  return new Iterable(function():Function {
    var i:uint = start;
    return function():uint {
      return i++;
    };
  });
}

遅延リストの構造を「次の要素を返す関数を返す関数」から「cdrが遅延評価されるconsセルを使ったリスト」にしただけでこれだけのシンプルさが得られるなら、あれをもう一度書き直してもいいような気がしています、またいつか!

以下余談:

AS3は特殊形式を扱えないので遅延評価させたい式はいちいち無名関数で包むことになりますが、まあそれは仕方がないとして、末尾最適化がない(ですよね?)のでちょろっと再帰しただけで即スタックオーバーフローするのが終わっています。従って、ストリームの操作の中にはwhileと代入の形に翻訳せねばならないものがあるのが残念なところです。