Question

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

Was it helpful?

Solution

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.

OTHER TIPS

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)
})
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top