4 ms·
Very interesting piece. It sounds a lot like how exceptions be used to implement non-error control flow [1]. The one bone I have to pick is the juxtaposition of
by acjohnson55 11y ago
Very interesting piece. It sounds a lot like how exceptions be used to implement non-error control flow [1]. The one bone I have to pick is the juxtaposition of PFP and imperative as opposites. Certainly it's the case that PFPers can and do implement imperative logic monadically, but it's also the case that imperative programmers often use frameworks that largely treat the business logic, where most of the programming is actually done, as more or less pure functions. Moreover, explicitly hybrid languages like JavaScript, Scala, Rust, Swift, etc. seem to be where a lot of the practical PL excitement is these days. I think the real debate is in the best patterns to use for particular generic problems. That's the core of the blog post of course, I'm just disagreeing with some of the rhetorical framing.
Anyhow, the premise reminds me a lot of What Color Is Your Function [2] and its critique of async programming. I think monads are super useful and intuitive when representing data. Promises/futures blew my mind, once I finally understood them, but I think there are important points about how they can become extremely cumbersome within a large architecture. I have to admit that I'm starting to agree that they may be a dead end, no matter how much syntactic sugar you sprinkle on it.
I think the big issue is that if you can't pull data out of a monad, you can't really encapsulate its logic. For containers, this isn't much of a problem, because the monadic data structure is either inherent to the data itself or you can fold your way down to something more primitive. In those cases, the monadic model seems completely reasonable and very nicely encapsulated to me. I'm not sure I buy the idea that scoped continuations should replace this monad usage.
Connecting back with async programming, I wonder how this jives with the actor model, which has been so widely praised as a model of concurrency that is conceptually simple, easy to reason about, fault tolerant, and imperative. When the author mentioned the thread being the atom of imperative programming, actors immediately came to mind.
Lastly, much like monads, futures and every other abstraction out there, the usefulness of scoped continuations may come down to how easily it can be expressed and comprehended within real programming languages. I found the examples in the original talk and the blog post to both be rather difficult to follow. The former, probably because of the use of = to select the scope and the latter because of the verbosity of Java. It would be interesting to see if there's a syntax that really captures the operation in an intuitive way.
[1] http://stackoverflow.com/questions/2742719/how-do-i-break-out-of-a-loop-in-scala http://stackoverflow.com/questions/2742719/how-do-i-break-ou...
[2] http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y...
- pron 11y ago> The one bone I have to pick is the juxtaposition of PFP and imperative as opposites. Well, I most certainly didn't say FP and imperative are opposites; quite the contrary: most FP languages are imperative. Part of the confusion is that there is no definition of FP. PFP, OTOH, is well defined: it is a style of programming where all functions are pure. If you can write impure functions, you're not doing PFP, and if you're doing PFP, you can't write impure functions. > I'm not sure I buy the idea that scoped continuations should replace this monad usage. I'm not entirely sure what you mean by "this usage" (lists?), but, like I say in the talk, I think monads are great for parallel streams, where you explicitly don't care about the stack context. > I wonder how this jives with the actor model... When the author mentioned the thread being the atom of imperative programming, actors immediately came to mind. Exactly. Threads (and by that I mean any thread implementation, not just kernel threads) are the best use of continuations, and blocking actors like Erlang's (or our own Quasar) make great use of (lightweight) threads, as do Go's goroutines (and Quasar fibers). > may come down to how easily it can be expressed and comprehended within real programming languages. I found the examples in the original talk and the blog post to both be rather difficult to follow. My opinion is that it's not important for scoped continuations to be directly exposed at all, and if they are, they should be rarely used directly. Using them to create lightweight threads solves almost all of the problems with the monadic style, and the code looks just like any plain-old thread-blocking code (we've had very good success with that in Quasar; Code stays the same, but instead of blocking a kernel thread, it blocks a fiber; the APIs don't even need to change). > The former, probably because of the use of = to select the scope I admit that when I gave the talk the precise details of the API and usage weren't yet clear to me, which is why I wrote the post. > because of the verbosity of Java Where does Java's verbosity bother you here? (although I'm probably biased, as I like Java's, or Go's, intentional verbosity)
- acjohnson55 11y agoFair point on PFP. > I'm not entirely sure what you mean by "this usage" (lists?) [...] By "this usage", I meant containers, generally. Maybe algebraic data types would be more specific. > [...] blocking actors like Erlang's (or our own Quasar) make great use of (lightweight) threads [...] Have you been following the Reactive Manifesto [1] and reactive streams [2]? If so, do you have any thoughts on whether this it builds out design practice in a complementary way to your suggestion here, or is it divergent? > Using them to create lightweight threads solves almost all of the problems with the monadic style, [...] My concern here would be whether you'd then be recreating the old problem you mentioned of having many implicitly monadic constructs in imperative programming but no good way of adding your own. In the analogous case in PFP, even if the continuation monad is the mother of all monads (and I haven't finished reading that post you linked to), I'd have to imagine it wouldn't be a whole lot of fun to use it exclusively. Or else people would do it! > Where does Java's verbosity bother you here? I probably should have withheld comment on Java's verbosity. There's probably nothing wrong with it. I think I'm just used to Scala and dynamically typed languages. Anyway, awesome work. You make a lot of great points. [1] http://www.reactivemanifesto.org/ http://www.reactivemanifesto.org/ [2] http://www.reactive-streams.org/ http://www.reactive-streams.org/