سؤال

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

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

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/

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)
})
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top