call/CC with closures

这一生的挚爱 提交于 2019-12-10 15:27:34

问题


Wikipedia mentions that "In any language which supports closures and proper tail calls, it is possible to write programs in continuation-passing style and manually implement call/cc."

How would one implement this function in for example in javascript? I know that javascript doesn't do tco, but assuming that stack space doesn't run out


回答1:


It is not possible to write a call/cc implementation in JavaScript:

JavaScript does not meet the requirement of "proper tail calls" (no additional stack creation). However, I believe that a form of continuations, such as that found in Jetty, using exceptions is possible. "CPS" is as easy as passing a function-object, although ultimately it runs into stack issues as well unless backed out occasionally.

Happy coding.




回答2:


Yes it is possible. See this question. This is how you would implement it:

Function.prototype.async = async;

function async() {
    setTimeout.bind(null, this, 0).apply(null, arguments);
}

function callcc(f, cc) {
    f.async(cc);
}

Then you may use it as follows:

pythagoras.async(3, 4, alert);

function pythagoras(x, y, cont) {
    callcc.async(square.bind(null, x), function cc(x_squared) {
        callcc.async(square.bind(null, y), function cc(y_squared) {
            add.async(x_squared, y_squared, cont);
        });
    });
}

function square(x, cont) {
    multiply.async(x, x, cont);
}

function multiply(x, y, cont) {
    cont.async(x * y);
}

function add(x, y, cont) {
    cont.async(x + y);
}

You may fiddle with the demo here: http://jsfiddle.net/brZrd/




回答3:


it is possible

https://github.com/zaoqi/callcc.js/blob/master/callcc.js

async function callcc(f){
return await new Promise((resolve,reject)=>{
const resolve_packed=(v)=>{
    resolve(v)
    return new Promise((resolve,reject)=>{})
}
f(resolve_packed).then(resolve).catch(reject)
})
}

use it:

test('test1',()=>{
expect.assertions(1)
expect((()=>{
async function q(k,v){
    console.log('testing1')
    await k(v)
}
return callcc(async function(k){
    console.log('testing0')
    await q(k,133)
    console.error('test error')
})
})()).resolves.toBe(133)
})


来源:https://stackoverflow.com/questions/8282119/call-cc-with-closures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!