Tim Bray on Clojure and Erlang

A short comparison (plus some links) of Erlang and Clojure solutions to the simple problem of running a counter in a separate thread.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

i like the last line

"If only Clojure weren’t a Lisp..."

because i was thinking it would have been nice if the Erlang version was in Lisp Flavoured Erlang to be all nice and paren-y like the Clojure code would be. :-)

Why is RPC bad

In the "contributions" section, there is that comment:

From: Ulf Wiger (Oct 30 2009, at 17:01)

There have been applications written in erlang where the messages passed to some processes where indeed just a function call spec (an "MFA" in Erlang speak, or a {Module, Function, Args} tuple). The idea is that this would be very convenient, since you save a lot of typing otherwise needed to specify _what_ specific functions the server is intended to serve.

This style of programming has its uses (indeed, the rpc module in OTP works exactly like this), but experience shows that it makes for a terrible style of concurrent GOTO programming that quickly renders your code unreadable unless you can contain it all within a fairly small body of code.

I read that RPC behaves badly because remote calls are not equivalent to procedure calls, there are transport errors, remote host failures or upgrades etc.
But what does Ulf mean by concurrent GOTO programming? What is considered "good" programming style in Erlang?

System A calls function f on

System A calls function f on System B, which calls function g (twice) on System C, etc. Now function f fails. Where was the failure? The control flow is now all over the place. If you choose to send asynchronous messages rather than open synchronous channels, and if you program in that style, then things are easier to reason about. But you can build rpcs on top of message passing and message passing on top of rpcs, so the issue isn't expressiveness -- rather it is coupling. At least, I think that's the gist of the argument.

There are also proven

There are also proven debugging tools for distributed message passing.

There has never been a good way to debug RPC.

The other problem is that there is shared knowledge of interfaces between the client and the caller. The message paradigm is created to solve this physical coupling issue!

Is RPC considered bad because too rigid?

Is that not good to have some shared knowledge between the two clients?
Discoverability is nice, but I don't think it is what you use generally.

The coupling occurs if the RPC protocol is fixed by the language, which is the same with message passing. There can also be voluntary coupling (eg. class verification, versioning).

I am thinking about adaptors to translate between the remote client protocol and the host language syntax.

The protocol used to interface with a remote client is an implementation detail, it does not need to be exposed to the program. Except if the remote client interface is too complex then you probably can't express it in the host language easily-- not sure message passing helps much here.

proven debugging tools

The products in the link look nice. I notice that the debugger works with OpenMP, would you consider OpenMP as "distributed message passing" in the Erlang nothing-is-shared sense?

Good question

OpenMP is like a rudimentary assembly language for distributed computing, without any features to help you avoid duplication. This is because the programmer is responsible for annotating sections of code with hints to OpenMP (#pragma omp ...) for how to divide computations. Moreover, there is no guarantees that the programmer is not splitting things up incorrectly (due to aliasing and undecidability), so a major use case for that debugging tool you just saw is debugging crap like that. Finally, because programmers are annotating code, they are effectively stating things twice, making maintenance more difficult.

In that sense, it is not shared nothing like how Erlang programmers talk about shared nothing.


Where was the failure?

A "distributed stack trace" would answer that, wouldn't it?
I suppose your question is more about handling and recovery than about locating the error in the logs. Do you have a real-life scenario in mind?

About synchronous channels, message passing can be synchronous too. Remote procedure call can be asynchronous with futures.

I should add that Joe

I should add that Joe Armstrong did an excellent job of summarizing some of the key issues: http://armstrongonsoftware.blogspot.com/2008/05/road-we-didnt-go-down.html

Steve Vinoski also has much of interest to say: http://steve.vinoski.net/blog/category/rpc/