I am actually reading through the book right now I have to say Joe did a great job with the book. Explaining concepts I thought was difficult in a clear manner. It's fun going through the examples as well. A real page turner for me.
Interesting to observe that on the subject of Erlang, a very mature and powerful language, along with its incredible OTP framework, there are maybe ten books published (Armstrong lists six; I'm seeing a few others on Amazon).
Compare that to the entire bookcases that have been written about Java, .NET, Visual Basic, etc.
Erlang has few books but they are a good read.I started reading learn you some erlang just because I found it unusual for a programming book to have bearded octopus and before I know it I was totally hooked!
A see a couple of reasons, some positive and some negative:
* Erlang is not as popular.
* It is rather a niche language suited for some domains but it is not for others (compute oriented languages). So not many "How to write games in Erlang" or "Statistics in Erlang"
* Erlang documentation is pretty good. It is not pretty (look like it its style got stuck in late 90s), but it is comprehensive
* Erlang programmers I find are good self-starters and of higher quality than other programmers. It is just what I observed I maybe wrong. This is the same as Haskell or Rust perhaps. That means they learn and find out stuff on their own.
* Erlang is self-consistent. There are not that many ways to do one thing. Not like Scala, C++ or Java. That means there is usually a canonical good way. That also means less "Erlang patterns". Usually large number of "patterns in X" means there is some deficiency in the language or library. That means a small cottage industry of writing "patterns in X" books.
It is built with concurrency in mind, from the ground up, making it much easier to write concurrent programs than when using the traditional languages that you've listed.
1) Every process in Erlang manages its own memory and has its own GC. This means that GC'ing one process will not stop the world.
2) Erlang has multicore compatibility baked in, through its process-based model.
3) Erlang enforces pure message-passing at a language level, so there is no shared state. This allows concurrent programs to be written much more easily than in languages where one has to manage shared state.
4) Referential transparency - to the programmer, one can use virtually the same code to pass a message on a remote Erlang process and an Erlang process on the same machine.
5) Fault-tolerant and self-healing mechanisms built in.
This is not an exhaustive list -- it just gives you an idea.
> 1) Every process in Erlang manages its own memory and has its own GC. This means that GC'ing one process will not stop the world.
Most processes are so short lived, and with message passing, that the GC often might not have to do anything. You just free all memory allocated by processes.
> It is built with concurrency in mind
Like Go on crack. Processes are cheap and are used the same wether they exist on the same machine or a different one. And it has pattern matching.
Adding to my original post, every process is managed by Erlang's VM. Whereas in many languages, concurrency constructs are mapped to OS threads, Erlang has virtual threads that it manages for you. If the VM detects a multicore processor, it will know how to -automatically- map its virtual threads to take advantage of them.
Also, the actor-based style of programming tends to model real-world interactions more cleanly than OO code, leading to potentially clearer and more maintainable code.
Yes! Just look at the code required to serialize objects, send them between 2 computers, and deserialize them. You would need to do all of that stuff manually. Even with a library like AKKA, I don't think it's nearly as simple as it is in Erlang: 1 line to connect, 1 line to do the remote call.
In Erlang you can remote into servers, examine their message queues, update the running processes with new functions, etc. You can guess what that would take with those other languages.
You could roll your own supervisor process and have things automatically restarted when you lose connection to them in the other languages, but it's already baked into Erlang.
I don't know of another language that put fault tolerance as top item on the design "todo" list. Erlang did that. Processes are lightweight (only a few KB overhead each). Processes have isolated heaps, much like OS processes in fact. That is rather unique. People who have been burned by large concurrent C++ programs crashing with segfaults, dangling pointers and rare race conditions stemming form concurrency units (callback chains, threads) stepping each others' toes, will appreciate that.
Its VM is rather elegant and powerful. It is a marvel of engineering if you wish. O
Even though rather advanced, I would suggest reading blog posts by Jesper Louis Andersen he covers some of these topics at the level I like.
The books are also good. There is also Learn You Some Erlang book, I even have the dead tree version of it (but there is a free online version as well). That also touches on some uses.
I think it makes more sense to think of erlang like a cluster machine and fault-tolerant operating system that comes with one programming language (two, if you count elixir).
If "cluster OS" or "this thing needs to keep running for 10 years straight, even through software upgrades" sounds like it addresses problems you face, then look into erlang.
If not, then you'll probably find it cool, but not particularly useful.
Erlang is rather fascinating. It is a relatively old language and for being such an old language it managed to keep consistency and didn't explode into an all singing all dancing pony with 100 ways of doing everything. It syntax is strange compared to run of the mill curly bracket languages, but it is self-consistent.
It is also interested because it is adding rather fundamental features to it like maps. Yes, yes, all the modern languages have them and Erlang is about to them too! despite being a rather ancient language.
> It is also interested because it is adding rather fundamental features to it like maps. Yes, yes, all the modern languages have them and Erlang is about to them too!
I don't know whether I'd say Erlang didn't have (hash-)maps before.
Each Erlang process has always had a "process dictionary." If you think of these as equivalent to another language's thread-local variables, this seems like a wrong comparison--and people tend to avoid using the process dictionary for this reason.
But if you think of processes as Erlang's objects, in the OOP sense[1], then the an object's process dictionary is equivalent to that object's "slots", in the Python/Javascript/Lua sense. And so, if you want a (automatically concurrency-safe!) map, you just make a new "map server" object that responds to get and set messages by manipulating its process dictionary. Which is exactly how you'd expect a mutable hashmap object to work in any other language.
Or, you can avoid this low-level stuff by using ETS tables instead, if the difference between O(log N) and O(1) performance doesn't much matter to you... but if you think about it, ETS tables are basically just doing this same thing: creating a separate object/process that responds to messages to hold your mutable state, rather than representing it as an on-stack data structure.
---
[1] Alan Kay was probably describing something closer to Erlang (or Simula) processes, than Java "objects", with OOP. Here's the unabridged quote: http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay... . Note especially this part: "I thought of objects being like biological cells and/or individual computers on a network." Both of those conceptions necessarily involve concurrent computation on the part of each "object."
None of those offer "dynamic" records type feature. So you deserialize a json block (and for better or for worse json is here to stay). What should the output of that be? A new process with a process dictionary? A new ETS table? A proplist of sorts. Well it could be all of those the best answer is a map. Which is what we are about to get.
17 comments
[ 5.0 ms ] story [ 81.8 ms ] threadCompare that to the entire bookcases that have been written about Java, .NET, Visual Basic, etc.
* Erlang is not as popular.
* It is rather a niche language suited for some domains but it is not for others (compute oriented languages). So not many "How to write games in Erlang" or "Statistics in Erlang"
* Erlang documentation is pretty good. It is not pretty (look like it its style got stuck in late 90s), but it is comprehensive
* Erlang programmers I find are good self-starters and of higher quality than other programmers. It is just what I observed I maybe wrong. This is the same as Haskell or Rust perhaps. That means they learn and find out stuff on their own.
* Erlang is self-consistent. There are not that many ways to do one thing. Not like Scala, C++ or Java. That means there is usually a canonical good way. That also means less "Erlang patterns". Usually large number of "patterns in X" means there is some deficiency in the language or library. That means a small cottage industry of writing "patterns in X" books.
1) Every process in Erlang manages its own memory and has its own GC. This means that GC'ing one process will not stop the world.
2) Erlang has multicore compatibility baked in, through its process-based model.
3) Erlang enforces pure message-passing at a language level, so there is no shared state. This allows concurrent programs to be written much more easily than in languages where one has to manage shared state.
4) Referential transparency - to the programmer, one can use virtually the same code to pass a message on a remote Erlang process and an Erlang process on the same machine.
5) Fault-tolerant and self-healing mechanisms built in.
This is not an exhaustive list -- it just gives you an idea.
Most processes are so short lived, and with message passing, that the GC often might not have to do anything. You just free all memory allocated by processes.
> It is built with concurrency in mind
Like Go on crack. Processes are cheap and are used the same wether they exist on the same machine or a different one. And it has pattern matching.
Also, the actor-based style of programming tends to model real-world interactions more cleanly than OO code, leading to potentially clearer and more maintainable code.
In Erlang you can remote into servers, examine their message queues, update the running processes with new functions, etc. You can guess what that would take with those other languages.
You could roll your own supervisor process and have things automatically restarted when you lose connection to them in the other languages, but it's already baked into Erlang.
Its VM is rather elegant and powerful. It is a marvel of engineering if you wish. O
Even though rather advanced, I would suggest reading blog posts by Jesper Louis Andersen he covers some of these topics at the level I like.
http://jlouisramblings.blogspot.com/
The books are also good. There is also Learn You Some Erlang book, I even have the dead tree version of it (but there is a free online version as well). That also touches on some uses.
If "cluster OS" or "this thing needs to keep running for 10 years straight, even through software upgrades" sounds like it addresses problems you face, then look into erlang.
If not, then you'll probably find it cool, but not particularly useful.
Erlang is rather fascinating. It is a relatively old language and for being such an old language it managed to keep consistency and didn't explode into an all singing all dancing pony with 100 ways of doing everything. It syntax is strange compared to run of the mill curly bracket languages, but it is self-consistent.
It is also interested because it is adding rather fundamental features to it like maps. Yes, yes, all the modern languages have them and Erlang is about to them too! despite being a rather ancient language.
http://erlang.org/pipermail/erlang-questions/2013-May/073656...
I don't know whether I'd say Erlang didn't have (hash-)maps before.
Each Erlang process has always had a "process dictionary." If you think of these as equivalent to another language's thread-local variables, this seems like a wrong comparison--and people tend to avoid using the process dictionary for this reason.
But if you think of processes as Erlang's objects, in the OOP sense[1], then the an object's process dictionary is equivalent to that object's "slots", in the Python/Javascript/Lua sense. And so, if you want a (automatically concurrency-safe!) map, you just make a new "map server" object that responds to get and set messages by manipulating its process dictionary. Which is exactly how you'd expect a mutable hashmap object to work in any other language.
Or, you can avoid this low-level stuff by using ETS tables instead, if the difference between O(log N) and O(1) performance doesn't much matter to you... but if you think about it, ETS tables are basically just doing this same thing: creating a separate object/process that responds to messages to hold your mutable state, rather than representing it as an on-stack data structure.
---
[1] Alan Kay was probably describing something closer to Erlang (or Simula) processes, than Java "objects", with OOP. Here's the unabridged quote: http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay... . Note especially this part: "I thought of objects being like biological cells and/or individual computers on a network." Both of those conceptions necessarily involve concurrent computation on the part of each "object."