curious for those deep in programming languages, w...
# thinking-together
i
curious for those deep in programming languages, what's the general lang design community's take on continuation style passing i.e. • what're the unexpected problems in practice • why are they not commonly used/popular given they seem to keep getting reinvented
caveat: to me they seem getting re-invented given my currently shallow literature e.g. • clojure's transducers => contortions to express CPS using anonymous functions • monads => reinvention of CPS • effect handlers => constrained CPS?
I think it's a little bit like the koan of objects vs closures: http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html
i
👍 thanks, reading them now
is there modern "consensus" on what the RightWay™ is today? or phrased another way from my limited pov:
continuations => bad and hard to reason about ~=
goto
delimited continuations => better, more expressive ~=
jump
but still unpleasant to reason about/still forced to play human compiler • effect handlers => human usable, layman grokkable within 10 mins without esoteric knowledge about type theory/categories/monads/etc, so the RightWay™?
w
I came here to say what the slides to of compilers: that static-single assignment is easier to think about. Though continuations have a certain theoretical elegance, they generally mismatch use-cases so that you always end up wrapping them. Common Lisp conditions have always seemed better to me than exception mechanisms. Most exception (maybe just my exceptions) are bugs, and then you want to keep the stack, be able to drop into a REPL, figure out what's going on. The fact that exceptions often have a print_stack_trace method just goes to show that you actually want to keep the stack. The other main use of exceptions is for a quick escape from nested computation. After years, I think I've come over to the checked exception camp on those. In other words, if a checked exception doesn't feel good in a situation, an unchecked one isn't either, and you should be using a sort of condition system. AND then if the condition is the kind of thing where you may, for instance, want to get feedback to from the user, then you're likely going to want coroutines of some sort. I mean you were doing something step-by-step, but now it's broken, so set that aside, look for a fix, then come back to it.
i
so from my day of research, the tldr algebraic effects are structured delimited continuations that solve a lot of the problems with delimited continuations (~= all problems of unbounded dynamic typed callback programming)
the CL condition system is very close analog with limitations that it a. it can't restart outside of lexical scope (i.e. resume a continuation in a different stack) b. it can't resume multiple times
it is questionable whether those are necessary or even good, especially b.
j
I don't know how deep you want to go with this question, but the best web-visible resource regarding continuations of which I'm aware is: http://okmij.org/ftp/continuations/ ... in particular, on the topic of
call/cc
, I recommend: http://okmij.org/ftp/continuations/against-callcc.html
👍 1
d
I think it's useful for a programming language to use CPS behind the scenes (i.e. using callbacks in place of call stacks), as opposed to something one done manually (e.g. explicitly passing callbacks) just for the utility that it opens up: * Easy debugger (stop time, go back in time) * Easy implementation of exceptions, etc. * Async code can be written as if it's synchronous But I'm not sure CPS works that great unless you're essentially using a Scheme-like runtime
👍 1
This is the only example I know of that does this, though: http://lisperator.net/pltut/
👍 1
i
concur with @Jack Rusher @Dan Cook comments
for posterity/others, my overall take away after a week of implementing them and various other lang controls is 1st class delimited continuations are extremely powerful but are a pandora's box (~= a functional goto). Even though other things I mentioned are weaker forms of them (e.g. transducers), you do want the weaker forms as it scopes what someone can do
imho, algebraic effects are the best form of them that are usable but even there, I think they need more scoping restrictions, especially in non-functionally pure languages