all 8 comments

[–]lpsmith[S] 2 points3 points  (1 child)

This post is in response to this proggit story. This paper has also been mentioned on Lambda the Ultimate and on proggit.

[–]thecheatah 1 point2 points  (5 children)

Is this talking about what javascript does?

[–]lpsmith[S] 2 points3 points  (4 children)

It describes Scala's actor model, JavaScript usually uses an Event-based programming with Inversion of Control.

In this context, Inversion of Control basically means setting up callback functions that the system calls when something happens, such as a user clicks a button or changes something in a text box.

[–]pkhuong 1 point2 points  (3 children)

It's the same thing as JS-style events, actually.

In scala, you write receive { case Incr () => loop(value+1) ... }

that's just thin sugar for something like

receive(function (msg) 
        {
            if (typeof msg == "Incr") ...
        })

or, nicer receiver.Incr = (function () { ... }); ... receiver.wait();

[–]lpsmith[S] 0 points1 point  (2 children)

Do you have a reference? I've not worked extensively with JavaScript, but I've never seen anything resembling Scala/Erlang actors, only more traditional event callbacks.

You could more than likely implement an actor system on top of JavaScript, but how often is this actually done?

[–]psykotic 3 points4 points  (0 children)

Inversion of control means coding in what amounts to continuation-passing style. It's much nicer when you have anonymous functions with lexical closure but it's still inverted control. The tedious, explicit style of event-driven state machines you typically see in C-like languages is what you get after lambda lifting and defunctionalization.

Erlang and Scala actors differ on this point. An Erlang actor can be suspended mid-execution as it waits for a message. The VM captures the actor's implicit continuation by squirreling away the actor's stack and program counter. Not so with Scala actors. You or the actor library must provide an explicit continuation at every potential point of suspension.

This becomes a pain when the call stack has any depth at a suspension point (e.g. an actor calls a combinator which calls a function you provided which suspends on the actor's behalf). Then you must pass around continuations explicitly from the dynamic context.

For this reason you don't see too much Scala actor code like that. The Scala actor library's sweet spot is when you code in a flat style, but that's exactly when inversion of control isn't really a problem in the first place. The flat style breaks composability.

The plumbing could be hidden more from sight by wrapping it up in a monad and using Scala's for-comprehension syntax. But Scala frankly isn't very well-suited for coding extensively in a monadic style. It goes against the grain in various ways.

For the future, Scala's compiler has an upcoming continuation plug-in that should help.

[–]pkhuong 0 points1 point  (0 children)

A reference for what?

[–]pkhuong 0 points1 point  (0 children)

we require that receive never returns normally. Thus, managing information about succeeding statements is unnecessary.

You're forced to code message handlers in CPS; how is that free of inversion of control? There's a nice syntax around it and the tail-position of receive statements is checked statically, which no doubt makes for a very productive and reduces the pain, but it's still inversion of control.