13 ms·
Erlang is a powerful language, IMHO it stands out because of 3 features: - Actor Model - Pattern Matching - Hot code replace Yet HotSpot is more performant
by maximveksler 14y ago
Erlang is a powerful language, IMHO it stands out because of 3 features:
- Actor Model
- Pattern Matching
- Hot code replace
Yet HotSpot is more performant VM then erlang's VM is. Now, if those features could be implemented on top of the JVM it would (to me at least) render erlang to be irrelevant.
So let's examine what is currently known.
- Actor Model: An example of a massive implementing effort of Actor model would be scala's Akka framework http://akka.io/ http://akka.io/
- Hot code replace: I don't know the answer to whether HotSpot lame code swapping implementation can be fixed to act like erlang does it. http://scala-programming-language.1934581.n4.nabble.com/how-to-steal-Erlang-s-hot-code-update-for-Scala-Java-td1989938.html http://scala-programming-language.1934581.n4.nabble.com/how-...
- Pattern Matching: As for pattern matching, to my understanding this can be implemented on top of the JVM, if one wishes to. http://news.ycombinator.com/item?id=2784086 http://news.ycombinator.com/item?id=2784086
- pka 14y agoYou're forgetting about OTP, Erlang's battle tested framework that covers about any edge case conceivable in a concurrent world. By themselves, you could probably produce hacky actors, pattern matching and hod code swap implementations in most dynamic languages (and on VMs like NET or JVM) nowadays, but it's the whole package that has remained unmatched so far. Not to mention Erlang's live console and logging capabilities which are indispensable when it comes to diagnosing crashed services or inspecting live systems and gathering stats. The fact that Erlang's data structures are immutable allows OTP to give you a very detailed report containing the exact state before the crash and the message that led to it, while in Java and most other languages your best bet is just an exception trace - and then you would have to guess what exactly went wrong because you don't have the system state anymore and can't recreate it easily for that matter. You can imagine that this makes debugging an Erlang application a joy - at least as joyous as it can get. One other important aspect of OTP are supervisor hierarchies - Erlang is built around the idea that if something can fail, it will - so systems should be designed in such a manner that failure in one component doesn't tear down the whole system. Services are carefully subdivided into autonomous submodules, and if a module crashes OTP will attempt to restart it and continue its operation if possible. Imagine a png conversion submodule crashing because of a faulty png header - in a Java system this would most probably throw an IndexOutOfBoundsException and down comes your whole backend. Erlang/OTP would just note that the converter has crashed and then restart it. It can do that because the converter doesn't affect or depend on some interconnected, global, "complected" state and thus can be easily started and stopped at will. Of course, Erlang's solution to concurrency is no silver bullet - you can still create deadlocks if you aren't careful and you can still create global state by abusing named processes, but it makes a lot of things a lot, lot easier. edit: one more thing - Erlang's hot code swap support is really one of the most beautiful things I've seen when it comes language features. Now, swapping code by itself isn't such a big problem - you can do this in C as well by just reloading a DLL or in Java by un/reloading a specific class - but the tricky part is about swapping state, and this is where most imperative languages fail hard. Said otherwise, when you update your service, you not only want to update your code but also your data structures. For example, if you have a class/struct like this: struct person { string name; int age; }; and would like to add an additional field `ageString` to it, for whatever purposes, how would you go about doing this in a more conventional language? You would have to track all usages of `person` somehow, and then replace the in-memory representation with the new version while making sure that no thread is reading or writing data, then swap the code while being careful that no new code is reading old data or vice versa. In fact, in most systems I've worked on such a thing would be almost impossible. Erlang's processes and immutable data structures allow you to do just that - and as painless as possible. You provide a function that converts old state to new state (in this case containing the field `ageString`), the new code which operates upon the updated data structures and let Erlang do the rest. All messages that come in while the swap is taking place will be queued up and delivered later. Moreover, if the update introduces a bug, you can as easily downgrade as you did upgrade. And all this while your service is up and running!
- theatrus2 14y agoScala and Akka solve many of these problems on the JVM, with a strongly typed language to boot. I love Erlang, but it's not all roses either.
- malkia 14y agoGood stuff. Reminds of me Common Lisp's http://clhs.lisp.se/Body/f_upda_1.htm#update-instance-for-redefined-class http://clhs.lisp.se/Body/f_upda_1.htm#update-instance-for-re...
- blaforge 14y agoExceptions can be quite problematic. This is why JActor has taken such pains in its exception handler. One particularly nice feature is that, since JActor supports 2-way messages, the default exception handler passes exceptions to the active exception handler of requesting actor. https://github.com/laforge49/JActor https://github.com/laforge49/JActor
- rdtsc 14y agoThe main power of Erlang comes from the ability to build fault tolerant and highly available systems. Fault tolerance was the main motivator behind Erlang's existence, not any of the thing you mention. Two of those things (actor model and hot code replace) fall out of that one requirement. Fault tolerance needs process isolation, that leads to actor model. Minimization of shared state leads to a immutable data structures + a functional approach. High availability and tolerance for upgrade downtime leads to hot code replace. And fault tolerance is exactly what JVM doesn't have. It shares a common garbage collector and there are other things. That is the main problem with those who claim "oh here is a faster Erlang library in language X", yes, one can copy some of the features into language X but unless full process isolation is copied, it is not really an Erlang replacement library/lanuage.
- asabil 14y agoYou can add the soft realtime characteristics of the VM to the mix. That's not something you can just add to the JVM as a library either.
- billrobertson42 14y agoYou're either realtime or you're not. If you have hard and fast time requirements to perform certain actions then you're real time. (e.g. 3 ms. to decide whether or not to turn the cruise missile or it hits a hospital). There is no 'soft' realtime.
- rdtsc 14y agoThere is soft realtime. You don't have to have hard and fast time requirements, or nothing, you can have more relaxed statistically defined requirements. That is soft realtime. Systems are not divided into cruise missile control systems and everything else. There is a continuum in between. A phone system where the calls need to routed in the 100 milliseconds or less 99.999% of the time is acceptable for example, while one where no such guarantees can be provided at all is not acceptable. It is not a realtime systems but it is pretty close, so it would be called soft realtime.
- edwinnathaniel 14y agoHotswapping: JRebel.
- blaforge 14y agoTake a look at JActor, a high-throughput Java actor framework. It gains its speed by operating mostly synchronously and delivers between 80 and 200 million messages per second, depending on the mode of delivery. https://github.com/laforge49/JActor https://github.com/laforge49/JActor