Jesper Louis Andersen writes about Erlang internals, including scheduling, concurrency versus parallelism, crash handling, and comparisons with Haskell.
HN commenters call it a very nice blog and cite it to explain Erlang's concurrency model, process crashes, and error handling in servers.
Never say "shared state" and "threading" in the same sentence.
If anything, all languages need to move to an Erlang shared-nothing model. But, Erlang was doing all this back in the 80s, so people have to re-invent it worse in the 2010s to feel special. You can't just go around using things other people made (OPC—other people's code) that just work, you have to make it your own and start your own conferences and books and webinars and vine instaslacks.
Erlang is also preemptive (bumping reductions) so your "long running computation spinning on a thread" problem goes away too. Though, we can't say "goes away"—sounds too much like Go—how about it "erlangs away" the problem?
Decent write up on erlang scheduling at http://jlouisramblings.blogspot.com/2013/01/how-erlang-does-scheduling.html?view=classic
Also see decent writeup about shared-nothing at http://jlouisramblings.blogspot.com/2013/10/embrace-copying.html?view=classic
Erlang also has per-process (green thread) heap/GC (i.e. no 'stop the world' required), full load balancing over your CPUs, unbelievably useful pattern matching, atoms/symbols, full serialization of all native data types, built with network distribution in mind from the ground up, plus a syntax that doesn't look like somebody woke up from the 70s in 2010 and decided to write a new language just like their old favorite language. Any knocks against Erlang syntax is because it stands on the shoulders of giants, not because somebody made it in 2010 and…
I think the opinions expressed in this article are valid.
However, I don't think the inability of current JavaScript to do async I/O without callbacks is Node's biggest problem. As others have said, it works for smaller projects (and even has some geek appeal). And as Havoc Pennington and Dave Herman have explained, generators (which are coming with ECMAScript Harmony) and promises will eventually provide a very nice solution. So Node has a path to grow out of the callback model without giving up its single threaded paradigm.
http://blog.ometer.com/2010/11/28/a-sequential-actor-like-api-for-server-side-javascript/
http://blog.mozilla.com/dherman/2011/03/11/who-says-javascript-io-has-to-be-ugly/
The bigger problem (which I don't see getting solved anywhere down the road) is the lack of preemptive scheduling, which is available in Erlang or on the JVM. What you see under high load with Node is that latency is spread almost linearly over a very wide spectrum, from very fast to very slow, whereas response times on a preemptively scheduled platform are much more uniform.
http://jlouisramblings.blogspot.com/2010/12/differences-between-nodejs-and-erlang_14.html
And no, this is something that can't be solved by distributing load over multiple CPU cores. This is problem really manifests itself within each core, and it is a direct consequence of Node's single threaded execution model. If anybody knows how to solve this without resorting to some kind of preemptive threading I'd…
Erlang processes are nothing at all like Unix processes. They are much, much smaller memory-wise as well as in terms of spawning/killing speed as they do not rely on system calls but rather the Erlang VM (which is highly tuned for these purposes).
Yes, there is a small overhead incurred when copying data between processes because the VM is truly copying the data[1], but the benefit gained is that you get per-process heap isolation (references can't cross process heap boundaries). This is important because in languages like Java or Go, one misbehaving bit of code that is causing a lot of GC to happen can "stop-the-world", and make your entire system pause (and it does happen[2]). This is not acceptable when writing soft real-time code, like say an auction system.
I'm not sure why you think an Erlang program is more heavyweight than Go. Is it due to Go programs being compiled to binary? Erlang can do that as well,[3] although it's not often done as Erlang requires a runtime, and it's often simpler to use a separate runtime. But you should know that Go also requires its own runtime to run Go programs[4], it's just that it is statically linked into your compiled code (which is what makes the resulting binaries so huge). But Erlang could do the same thing, it's just not really an industry practice.
[1]: http://jlouisramblings.blogspot.dk/2013/10/embrace-copying.html
[2]: https://groups.google.com/d/topic/golang-nuts/S9goEGuoMRM/discussion
[3]:…
There was a really good post earlier this year about how Erlang does scheduling (http://jlouisramblings.blogspot.fr/2013/01/how-erlang-does-scheduling.html). I think one of the important takeaways is this: "[Erlang] values low latency over raw throughput, which is not common in programming language runtimes". It's worth a quick read.
Ultimately I find that Erlang's strength is not one thing or another, it's a combination of all of its traits: from the functional nature, to OTP for providing a consistent application structure, to its VM; all of these things put together make it interesting and useful.
I've yet to get into Haskell (I will eventually) but I really do find that constructing applications in a functional manner, with state being stored in independent processes within the running application, is a superior way to build systems.
One final note: I really like Go as well, for very specific reasons. Go's resource usage (both in terms of CPU consumption and RAM) is soooo nice, especially coming from Ruby. I was never a C programmer but I can wrap my head around Go and use it to build low resource usage apps with specific purposes, and sometimes this is exactly what is required.
Not at all. Erlang isn't useful for modern parallel computing as we know it, which is usually done as some kind of SIMD program; say MapReduce or GPGPU using something like CUDA. The benefit doesn't just come from operating on data all at once, but these systems (or the programmer) also do a lot of work to optimize the I/O and cache characteristics of the computation.
Actor architectures are only useful for task parallelism which no one really knows how to get much out of; definitely not the close-to-linear performance benefits we can get from data parallelism. Task parallelism is much better for when you have to do multiple things at once (more efficient concurrency), not for when you want to make a sequential task faster.
Maybe this will help
http://jlouisramblings.blogspot.com/2011/07/erlangs-parallelism-is-not-parallelism.html
and
https://news.ycombinator.com/item?id=2726661
You can certainly port slow Erlang code to C, but it's not as straightforward as doing so in, say, Python or Ruby. For one, if your C code crashes, it's not the calling Erlang process that crashes, but the entire VM [1]. Second, NIF implementations are supposed to cooperate with the BEAM scheduler and only run for 1ms at a time. jlouis points out that most NIFs fail at this [2]. Third (and maybe the expectation here is too great), binary data (structs, etc.) used/provided by NIFs are "magic binaries" which cannot be pattern matched and are represented in crashes, the REPL, etc. as "<<>>" which can be confusing [3].
[1] http://www.erlang.org/doc/man/erl_nif.html (see "Warning")
[2] http://jlouisramblings.blogspot.com/2013/07/problematic-traits-in-erlang.html#nif-abuse
[3] http://erlang.org/pipermail/erlang-patches/2011-April/002046.html