遅延評価のココロ

遅延評価ってこれであってるの?

評価しないでいいかもしれない状況なら変数(=関数)は評価しない.評価しないといけない状況になったときのみ評価する.
それは,パターンマッチ/returnを求められたとき.

つまり,評価されるのは他の関数に渡さなければならないとき.
モナドなら他の関数に引き渡すとき?

そういう風に捕らえていたんですが,あってますかね?

その後

以前に,このエントリ
で遅延評価ってできるんじゃない?と思ったんだけど,amachangさんが書いたのと似たような(amachangさんのが美しい・・・悔しい)方法(.e(),僕は.force())で解決しててちょっと嬉しい.

でも,ちょっとわからないのが,amachangさんの遅延評価は

var a = function() {
  return function(x) { 
    return x;
  }
};

してて,これだと,関数a(の処理)に値(引数)がわたるのは,評価の段階な気がします.

具体的には

a.e()(3)

とかしないと関数aには3が渡らなくて渡ったときにはすでに式は評価されるから,なんか違う気がする.

どちらかというと,

a(3)という形(?)はできてるんだけど,具体的にa(3)がいくらになるかはまだ計算されてない.
で,上に書いたように,実際に評価される時(.e())に値が決まる.

ような気がする.

amachangさんは

遅延とは引数がそのまま値を返す無引数関数で囲まれること

って書いているのですが,これが僕が馬鹿なせいかいまいちしっくり来ない.

と,思ったので

とりあえず恥ずかしげもなくこうじゃないん?と思ったのを書いてみる.

/* amachangさん作成 */
Object.prototype.force = function(){ return this.valueOf()};
Function.prototype.force = function() { return this.length != 0 ? this : this().force() };


//値を渡すけど評価は後でするfib関数
var fib = function(m){
    return function(){
        return (m <= 2) ? 1 : (fib(m-1).force() + fib(m-2).force());
    }
}

//値を設定(気持ち的には別の関数に関数ごと渡している)
var v = fib(10);

//例えば
g(fib(10));


//評価はここで
v.force();

う〜ん,でもコレだと無限リストをつくって「!!」で取り出すって処理ができないのか?
もうちょっと考えます・・・