JavaScriptでCPS

フィボナッチ関数をContinuation Passing Styleで書いてみました。
これで任意の時点で計算を止めたり後で再開したり、続けた後で戻ってみたりできるようになったはずです。
実行の処理は結局最後のwhileループが一歩ずつ進めているわけです。

なんかGUIに似てますね。

// Continuation Passing Style

// Task :: take None return next Task to do

function getFibTask(n, c){
    function FibTask(){
        if(n == 0 || n == 1){
            return c(1)
        }
        // return fib(n - 1) + fin(n - 2)
        // means:  (add(fib(n - 1)))(fin(n - 2))
        function next(value){ // get fib(n - 1)
            function add_(x){return x + value} // partial apply
            function next(value){ // get fib(n - 2)
                return c(add_(value))
            }
            return getFibTask(n - 2, next);
        }
        return getFibTask(n - 1, next);
    }
    return FibTask;
}

function getPrintTask(n, c){
    function PrintTask(){
        function next(value){
            console.log("result:" + value)
        }
        return getFibTask(n, next);
    }
    return PrintTask;
}

// Continuation:: take Continuation return Task
function FinalC(c){
    function FinalTask(){
        return None
    }
}

var task = getPrintTask(6, FinalC);
while(task){
    task = task()
}
    • -

追記:まえに悩んでいた、返り値を次の関数の引数にどう渡せばいいんだろう、という話、結局関数が複数の引数を取ると考えるから複雑なので、上のadd_みたいにカリー化してしまえば1引数だから入れる場所を悩まなくてすむというおはなし。前から後ろへじゅんばんにバケツリレーしていくだけでいいわけですね。