First of all, I agree with JUST MY correct OPINION's answer regarding learning Erlang. It's a mostly functional language (although concurrency plays a big role), and all of its features were added to go towards fault-tolerance and robustness, which is not exactly the same design goals as Javascript in the first place.
Second of all, leaving Node.js to get into Erlang is a bit misplaced. Node.js is a single server/framework that goes its way to do everything in an event-driven manner with the help of callbacks. Erlang has its own framework (OTP), but it's not on the same level at all.
If you plan on learning Erlang, I suggest my blog entry An Open Letter to the Erlang Beginner (or Onlooker) as intro reading before diving into tutorials.
The only thing you can compare Erlang and Node.js in, in terms of patterns and usage is how they are event-driven. However, there are two big major differences here. Node.js' model is based on callbacks bound to events. Erlang is based on message queues and selective receives. What are the implications in there?
First of all, if you do things in a callback-based manner, the only way you carry state around is to either have it global or get into continuation-passing style programming. Secondly, you have to care for the full event matrix yourself. One example of this is that if we imagine a very simple finite state machine: a mutex semaphore, event-driven.
The mutex semaphore has two states: locked and free. Whenever a given unit of computation (worker, process, function or thread) wants to gain access to the mutex, it has to fire an event that tells it 'I'm interested'. Now you have to care for the following types of events:
- The mutex is free and you ask to obtain the lock
- The mutex is locked by someone else and you want to obtain the lock
- The mutex is locked by yourself and you want to free the mutex
Then you have additional events to consider, such as timing out to avoid deadlocks:
- The mutex has been locked and you waited for too long, a timer to give up fires off
- The mutex has been locked and you waited just for too long, obtained the lock, then the timeout fired off
Then you also have the out of bound events:
- you just locked the mutex while some worker expected it to be free. Now that worker's query has to be queued so that when it's free it's handled back
- You need to make all of the work asynchronous
The event matrix gets complex very fast. Our FSM here only has 2 states. In the case of Erlang (or any language with selective receives and async with potentially synchronous events), you have to care about a few cases:
- The mutex is free and you ask to obtain the lock
- The mutex is locked by someone else and you want to obtain the lock
- The mutex is locked by yourself and you want to free the mutex
And that's it. The timers are handled in the same cases as the receives are done, and for anything that has to do with 'wait until it's free', the messages are automatically queued: the worker only has to wait for a reply. The model is much, much simpler in these cases.
This means that in general cases, CPS and callback-based models such as the one in node.js either ask you to be very clever in how you handle events, or ask you to take care of a whole complex event matrix in full, because you have to be called back on each inconsequential case that results from weird timing issues and state changes.
Selective receives usually allow you to focus only in a subgroup of all the potential events and allow you to reason with far more ease about events in that case. Note that Erlang has a behaviour (design pattern/framework implementation) of something called gen_event
. The gen_event implementation allows you to have a mechanism very similar to what's being used in node.js if that's what you want.
There will be other points that differentiate them; Erlang has preemptive scheduling while node.js makes it cooperative, Erlang is more apt to some very large scale applications (distribution and all), but Node.js and its community is usually more web-apt and knowledgeable about the latest web trend. It's a question of choosing the best tool, and this will depend on your background, your type of problem, and your preferences. In my case, Erlang's model just fits my way of thinking very well. This is not necessarily the case for everyone.
Hope this helps.