Live data from Hacker News

What Does "With Continuation" Mean? (2020)

forum.snap.berkeley.edu

31–40 of 60 posts

Re: What Does "With Continuation" Mean? (2020)

#31
post #22

Earlier quoted context omitted.

Approximately everything by Oleg is great! We half-jokingly considered renaming our Sydney Computer Science Paper Club to 'Oleg Fan Club'.

Hehe fun! Yeah, delimited continuations have much saner semantics than undelimited ones. Partly because they’re always well defined

Yes. It's also pretty clear how to use delimited continuations in a pure setting without mutation.

I'm not quite sure you can make use of something like call/cc without having at least one mutable variable or side-effect somewhere?

Re: What Does "With Continuation" Mean? (2020)

#32
post #23
post #12

I don't know whether it helps, but here's another explanation that doesn't involve a visual programming language: First, imagine that procedures (or functions) are first-class values, like in some languages are called "anonymous functions", "closures", "lambdas", etc. Now imagine that every procedure call is effectively a goto with arguments... and the familiar part about being able to return from that procedure, to…

An alternative way to look at for C/C++/pascal/… programmers it is by looking at the return keyword not as a keyword, but as an implicit argument that’s a pointer to a function. Imagine this would work: global fooBack global barBack main() { print foo() } foo() { fooback = return bar() return “foo” } bar() { barBack = return if randomBool fooBack(“bar”) else return “bar” } and that, 50% of the time, woud print “bar”.…

This is great, I finally understand how continuations work (since I now see how they might be implemented in the runtime). Thanks!

Could you provide a similar example of what delimited continuations are?

Re: What Does "With Continuation" Mean? (2020)

#33

So there’s a funny thing this doesn’t touch on: the semantics of call/cc is genuinely confusing to understand! There’s a related construct that’s much more legible and has a much easier to understand: call with delimited continuation! Oleg K wrote a very articulate piece about this some long time ago https://okmij.org/ftp/continuations/against-callcc.html

I think of `call/cc` as a parlor trick that helps introduce the concept of continuations more generally. Threads and co-routines are on the heavy-weight end of the concurrent programming techniques spectrum because they require stacks -possibly large, with guard pages and all- and encourage smearing application state onto that stack, increasing cache pressure. Continuation passing style (CPS) is on the light-weight e…

I think now I get why I find Python's async/await semantics (asyncio) so much more convoluted than Javascript's.

Javascript starts with simple callbacks. Those indeed have no stack, only a shallow list of local variables as state. Then async/await is modelled as a relatively straightforward syntactic sugar on top of that: An await call is still just a callback behind the scenes; if one async function awaits another async function, you get something that looks like a stack, but is really just a chain of callbacks.

In contrast, Python starts with coroutines, which do have a stack, then models async/await by surrounding them with a scheduling runtime. Unfortunately, for async code to be useful, you still need support for callbacks, so you end up with both: an await call represents a mix of suspended coroutine stacks and callback chains, which can be much more complicated to reason about.

Re: What Does "With Continuation" Mean? (2020)

#34
post #23
post #12

I don't know whether it helps, but here's another explanation that doesn't involve a visual programming language: First, imagine that procedures (or functions) are first-class values, like in some languages are called "anonymous functions", "closures", "lambdas", etc. Now imagine that every procedure call is effectively a goto with arguments... and the familiar part about being able to return from that procedure, to…

An alternative way to look at for C/C++/pascal/… programmers it is by looking at the return keyword not as a keyword, but as an implicit argument that’s a pointer to a function. Imagine this would work: global fooBack global barBack main() { print foo() } foo() { fooback = return bar() return “foo” } bar() { barBack = return if randomBool fooBack(“bar”) else return “bar” } and that, 50% of the time, woud print “bar”.…

I think `bar` being able to return from `foo` has little difference to throwing exceptions in various OOP languages. But the C-style paradigm makes it more confusing for different scenarios, like as you describe with calling the deeper "return" from main.

Re: What Does "With Continuation" Mean? (2020)

#35
post #23

Earlier quoted context omitted.

An alternative way to look at for C/C++/pascal/… programmers it is by looking at the return keyword not as a keyword, but as an implicit argument that’s a pointer to a function. Imagine this would work: global fooBack global barBack main() { print foo() } foo() { fooback = return bar() return “foo” } bar() { barBack = return if randomBool fooBack(“bar”) else return “bar” } and that, 50% of the time, woud print “bar”.…

I think `bar` being able to return from `foo` has little difference to throwing exceptions in various OOP languages. But the C-style paradigm makes it more confusing for different scenarios, like as you describe with calling the deeper "return" from main.

I'm not an expert, but I think the difference is that in exceptions, stack in unwound; while in continuations, all stack frame hang around in a sea of stack frames waiting to be garbage collected when no one holds a reference to them anymore. This would imply that you can jump into the same stack frame multiple times, or do other weird things.

Re: What Does "With Continuation" Mean? (2020)

#36
post #22

Earlier quoted context omitted.

Approximately everything by Oleg is great! We half-jokingly considered renaming our Sydney Computer Science Paper Club to 'Oleg Fan Club'.

Hehe fun! Yeah, delimited continuations have much saner semantics than undelimited ones. Partly because they’re always well defined

I like the notation "limited continuations" more than "undelimited". Drops the double negative and provides a pejorative element.

Call/cc still has a delimiter, it's just some second class thing above the scope of the current program that you can't do much with which thwarts composition. Let the programmer specify where the delimiter is and you get a less limited construct.

Re: What Does "With Continuation" Mean? (2020)

#37

The easiest way to think about continuations is to consider them a generalization of function returns. The continuation of a C function f() is the return address and the saved frame pointer of the calling function -- and that looks a lot like a closure, and that's because it is, except that a) you can only pass that closure one argument in C: the return value, and b) you actually can't get a value for this closure in…

Simpler still is to recognise that "call a function" and "return from a function" are different syntax over the same thing. They both mean "jump to somewhere with a convention about where to find state".

If you replace "call a function" with goto, and replace "return from a function" with goto, then it becomes immediately obvious that "continuation" is a name for where you're going to jump to next. It only looks complicated from the context of calls/returns/stacks.

Confusing call and return for different things is unfortunate but popular. It gives rise to things like four registers available for passing arguments and one available for returning a result, when the calling convention really should be symmetric.

"Continuation passing style" is what all function calls use - x86 writes the address of the continuation to the stack, more sensible ISA's pass it in a specific register - modulo language syntax that somewhat obfuscates control flow.

Re: What Does "With Continuation" Mean? (2020)

#38
post #23

Earlier quoted context omitted.

An alternative way to look at for C/C++/pascal/… programmers it is by looking at the return keyword not as a keyword, but as an implicit argument that’s a pointer to a function. Imagine this would work: global fooBack global barBack main() { print foo() } foo() { fooback = return bar() return “foo” } bar() { barBack = return if randomBool fooBack(“bar”) else return “bar” } and that, 50% of the time, woud print “bar”.…

I think `bar` being able to return from `foo` has little difference to throwing exceptions in various OOP languages. But the C-style paradigm makes it more confusing for different scenarios, like as you describe with calling the deeper "return" from main.

So the particular example here isn’t too different from exceptions. You’re unwinding the stack up to a predefined point— here, the callsite of foo, where with exceptions it would be up to the surrounding try/catch. Scala actually implements non-local returns (the only practical use I’ve had for call/cc) using exceptions: https://tpolecat.github.io/2014/05/09/return.html

Re: What Does "With Continuation" Mean? (2020)

#39

Earlier quoted context omitted.

I think `bar` being able to return from `foo` has little difference to throwing exceptions in various OOP languages. But the C-style paradigm makes it more confusing for different scenarios, like as you describe with calling the deeper "return" from main.

I'm not an expert, but I think the difference is that in exceptions, stack in unwound; while in continuations, all stack frame hang around in a sea of stack frames waiting to be garbage collected when no one holds a reference to them anymore. This would imply that you can jump into the same stack frame multiple times, or do other weird things.

> This would imply that you can jump into the same stack frame multiple times, or do other weird things.

Yep— this is how you can implement the `amb` operator with call/cc: https://ds26gte.github.io/tyscheme/index-Z-H-16.html

Re: What Does "With Continuation" Mean? (2020)

#40
post #21

I took a Scheme programming class where we did tons of stuff with continuations. I got obsessed and wrote all kinds of weird code. I even started using continuation passing style in Python. It was a dark time. Looking back, none of that code makes any sense at all. When I think back to my days of mucking around with call/cc my main emotion is relief that I’ve forgotten how it works. It’s a load off my mind

Continuation passing style is mostly a good tool for writers of compilers, and perhaps interpreters. It's very, very similar to single-static-assignment (SSA) style that will be more familiar to people coming from imperative languages.

How is it similar?
Post reply on HN