That's more or less how erlang work: by async message-passing, and it's used to build extremely (99.9999999%) reliable softwares. A "best-effort" semantic is more than enough: when you really care if the message has been received (that is to say most of the time), you make a "synchronous" call, which is really just two async calls (one in each direction), with a timeout. Even if the message back is just an acknowledgement that the message was received.
In Erlang/OTP it's wrapped in an actor behaviour called "gen_server", and the default timeout is 5000 milliseconds. If it timeouts an exception is raised, and a common strategy is to simply let the process crash, and restart to try again [0].
On the other hand it's not async call all the way down: it's only the calls between actors that are asynchronous: if you write a loop [1] within your actor then it's synchronous. To write asynchronous code you need to spawn new actors (which is trivial, and will always by default result in an exception being raised if something get lost or timeout after 5 seconds).
Note that when you write Erlang code the granularity of an actor is absolutely not the same as when you write OOP code: you don't wrap every data structure in a process, rather processes tend to be about processing data, or abstracting an IO point (a file, a socket, etc.) since the semantic is perfect.
[0] The implementation of all of this takes more or less 1 line of code, this is really the defaults.
Erlang != OOP as imagined by Kay... as I understand Kay's intent.
Erlang == "independent reliable units of computing". (I think Erlang programmers call them "functions"? Or maybe "processes"? AFAIR only the "process" level is subject to message loss, yes?)
I'm sure you're right about most of what you wrote, but that's not the point I was getting at.
EDIT: Just to expound: In Kay's conception even e.g. "==" inside a function would be a method invocation and it would be asynchronous (presumably taking two continuations, one for "equal" and another for "not equal"). This absurdity is why I fundamentally disagree with the Actor model (as a model of computation), but also with extremism such as Kay's.
EDIT: Btw, I call bullshit on the 99.9999999% reliable service unless you can come up with a reference. I know that Erlang/OPT is known for legendary relaibility, but I'm unsure on what that means: Does it mean "no interruption" on any given stream (e.g. phone call). Does it mean "no more than X connections fail"?
It's hard to put words in Alan Kay's mouth for him on this point but what he usually talked about was the biological model, specifically in regards to cellular units. In computing this does translate to independent, reliable, and redundant units. I'm not sure Erlang really takes it to the logical extreme but it certainly goes that direction.
It's interesting that detailed implementations of the idea become people's definitions (i.e. taking method-based dispatch as the analog to intercellular interaction). With Erlang, the method dispatch becomes modal via the currently active (or lack thereof) receive block in any given process, and I wonder if this captures something too specific or if this difference is worth making at the level of Alan Kay's OOP.
With that in mind, I think you're overstating the orthodoxy. The symbolic representation and execution semantics of messaging models aren't exactly the same. There is no reason == needs to be a "method invocation". If we step back, there isn't really a good definition of what it really means in todays runtimes and compilers anyway. Things get inlined, fast paths get generated for common cases, &c.. His point was more that late binding allows the system to avoid upfront knowledge or hard coding of all useful configurations in a piece of software. Leaving optimization to compilers and runtime systems seems to be the status quo these days.
I definitely agree that it's pretty hard to guess his precise intent, but that's exactly why I'm extremely skeptical of regarding him as some sort of prophet[1] on what exactly OOP "is". If you're always vague about what you mean, it's pretty easy to be a guru/prophet/visionary. AFAICT if one is going to claim to be a visionary (indirectly or otherwise) on the Actor model, I think Hewitt actually has the better claim -- much as I dislike him.
EDIT: Just on a minor point:
> There is no reason == needs to be a "method invocation".
Well, except that's what the Actor model and, indeed, Smalltalk (Kay et al.'s project) wants us to believe. I, of course, agree completely with you on this point. It's just a function -- simple as that.[2]
[1] Yeah, yeah, I'm exaggerating, but he did kind of bring on himself by continuing on his quest :). I bear no particular ill will towards him, but I do think he's caught in a web of having-to-be-brilliant-based-on-prior-performance-but-does-not-have-much-to-contribute... as befalls many academics and 'visionaries' (e.g. Uncle Bob with his recent rants). (Disclosure: I used to be an academic... and dislike Unclue Bob because he's far more dogmatic than he deserves to be based on documented experience.)
[2] Weeeeelllll, except to be able to decide equality you need to break the abstraction barrier. Which leaves an abstraction-committed OOP programmer with a bit of a dilemma. Me... I just choose the "Eq" type class. Problem solved and I didn't even have to expose any internals. Win win!
Fair point. I guess I never see the prophet thing but his ideas are interesting so I tend to follow Kay's work, if only to blend it with many other things, not so closely aligned with his views (ex: Lamport being close to opposite of Kay).
I think the whole pedantic "Alan Kay's OOP" thing comes from his coinage of the term vs. the practical application stemming from the Simula school of object orientation. I have no horse in the race so I really wish one sense of the term would be renamed.
The thing is, in Alan Kay talks, he more point to independent interpreters that can be sequential locally. But the idea is that you can at any point of time, swap that locality for a non local one if you need it.
That is the point behind object/actors/processes all the way down. As you only talk through message passing, noone has to know if you are sync or not inside the actor. You have a contract.
It's kind of weird to say that you have a contract in a dynamically typed language. Not that it would help - types say nothing about performance or reliability.
Moving a local computation to a remote server often fails because clients have implicit assumptions about performance, but nobody is explicit about deadlines except in hard real-time programming. So in practice you get timeouts at best.
> Erlang != OOP as imagined by Kay... as I understand Kay's intent.
You should check out the video[0] of Joe Armstrong interviewing Alan Kay - it seemed to me that Erlang was in some respects closer to what Alan Kay intended for OOP than even smalltalk was.
Indeed I was not commenting on Kay's intent, that I am not qualified to talk about. I was just adding the IMHO important precision that Erlang certainly didn't implement "==" as message passing. After all, Erlang was never meant to be OOP as imagined by Kay, it just happens to be similar in some important ways. AFAIK Erlang wasn't even modelled after the actor model or anything: it's "just" the result of an endeavour to reach maximum fault tolerance.
Regarding the 99.9999999% reliability, it's from Joe Armstrong about a system called AXD301. Here is the quote [0]: "Erlang is used all over the world in high-tech projects where reliability counts. The Erlang flagship project (built by Ericsson, the Swedish telecom company) is the AXD301. This has over 2 million lines of Erlang. The AXD301 has achieved a NINE nines reliability (yes, you read that right, 99.9999999%). Let’s put this in context: 5 nines is reckoned to be good (5.2 minutes of downtime/year). 7 nines almost unachievable ... but we did 9."
to be precise : Erlang was modeled from Smalltalk and Prolog, with a bit of Lisp. They did not knew about Hewitt and the Actor model when they created it, and only learned about it later.
about the nine nines : it was a british telecom company that claimed it, by extrapolating from a 14 node network during 8 months. I prefer to say that erlang make it easier to reach five nines, then enable you to go to seven nines if you really need it.
That's a matter for a compiler. If it's possible and efficient, inline everything so "object" just becomes dispatch tables with data pointers.
The actor model is a great way to unify remote and local processes with identical syntax, and solves a ton of syntax related issues such as overriding the default '==' operator, etc.
In Erlang/OTP it's wrapped in an actor behaviour called "gen_server", and the default timeout is 5000 milliseconds. If it timeouts an exception is raised, and a common strategy is to simply let the process crash, and restart to try again [0].
On the other hand it's not async call all the way down: it's only the calls between actors that are asynchronous: if you write a loop [1] within your actor then it's synchronous. To write asynchronous code you need to spawn new actors (which is trivial, and will always by default result in an exception being raised if something get lost or timeout after 5 seconds).
Note that when you write Erlang code the granularity of an actor is absolutely not the same as when you write OOP code: you don't wrap every data structure in a process, rather processes tend to be about processing data, or abstracting an IO point (a file, a socket, etc.) since the semantic is perfect.
[0] The implementation of all of this takes more or less 1 line of code, this is really the defaults.
[1] you need to write it recursively in Erlang.