News for hackers. Stuff that matters.
Re:All you need is call/cc (2013) by dragontamer on Wednesday August 25, 2021 @01:02PM (#28303995)
call/cc is a widget from Scheme / Lisp is a glorified come_here statement (where "come_here" is roughly the exact opposite of a "goto" statement). Its gloriously complicated but its applications are seemingly endless.

call/cc calls function "f" with a "come_here" label. Later, if you call the label, you return to the "come_here" point. call/cc saves off the stack-frame, so the "come_here" executes exactly as before (all local variables remain the same as they were before).

------

In C++ (call/cc doesn't exist, but we can imagine it in C++ lambdas)

    int f(auto come_here){
        come_here(25); // call the "come_here" function with the parameter 25
    }

    ...

    int x; 
    x = call/cc(f);
    // x now equals 25, because f called come_here with 25.
We can imagine the "come_here" function to be the exact line of code "x = call/cc". Now funny things can happen if you do ... funny things.

    int g(auto come_here){
        some_global_variable = come_here; // Yeah, lets store this come_here label off for later.
        return 0; // Notice, come_here hasn't been called yet. Return 0 normally.
    }

    int x; 
    x = call/cc(g); // defaults to the 0, for the "Return 0" in g.

    if(x < 100){
        some_global_variable(x+1); // Loop back to the x=call/cc command, and set x+1.
    }
Look Ma, I created an overly complicated while loop!

---------

EDIT: Now for fun, try _writing_ try, catch, finally statements (from Java). By saving off the right labels in the right order, you can experiment with try/catch, or other complicated maneuvers (ex: the "Ambiguous" operator, often named "amb").

This call/cc exists because scheme is catering itself as a meta-language. A language to build other languages out of.

Re:All you need is call/cc (2013) by ahefner on Wednesday August 25, 2021 @02:44PM (#28305320)
You don't need the global variable (at least, the Scheme equivalent does not - I'm not going to lawyer over how variable capture would work in a hypothetical dialect of C++ that added call/cc). Any variable in scope to be captured by 'g' will do. There may be some misunderstanding in your statement "all local variables remain the same as they were before" - the same bindings will exist, but the values are not restored to their values prior to the call/cc, such that any subsequent changes to those variables will be preserved, permitting exactly the sort of thing you used as an example (albeit using a global variable).
Re:All you need is call/cc (2013) by dragontamer on Wednesday August 25, 2021 @02:53PM (#28305441)
You're right: there's lots of little mistakes I have in that post. And I think the variable binding vs variable-values thing is a major mistake I left in there... and I appreciate the corrections.

Hopefully my relatively low-effort translation is useful to someone out there. But yes, I do admit that I "err on the side of incorrect", trying to favor simplicity in the explanation instead.

Re:All you need is call/cc (2013) by gpderetta on Thursday August 26, 2021 @05:28AM (#28312527)
Interestingly it is relatively straightforward to implement one shot continuations in C++ (i.e. call/cc1), but your example implicitly relies on being able to invoke a continuation multiple times. You can sort of implement multishot continuations with fork (more than just a curiosity, that's how reversible debuggers work in fact).