I've gotten some really good responses to my previous post about Erlang.
Wesner Moise has interesting things to say. I didn't know file corruption was big issue in Office, particularly with incomplete writes. I just assumed that problem they solved long ago.
Also interesting is this comment left by Judah:
I think that's a great improvement, but what about getting fewer bugs in software? At work, the bugs in our software -- probably 99% of the time -- are coding errors. When our software fails, it's almost always due to programming error. In the Erlang way, it would just retry my component that failed, then the parent component, and so on until the whole thing restarts. That's a bad system for us! With 99% of the time being programming error, restarting components isn't going to help in the least. The places where non-programming errors occur (such as network timeouts), well, a simply try/catch/error message is simple enough. We've designed our software to retry in such scenarios as well before issuing any errors. And even the error messages provide an easy way for users to retry such operations.
This is almost exactly my thinking too as I began to read about Erlang. The things they were talking about seemed to be solving problems I didn't have. I need solutions to MY problems, and here they're talking about imaginary restartable components!
But once you really get in to it, you realize the restartable components are just one part of a system. And actually, the restartable-component stuff not really in the basic Erlang language design, it's just a capability that "falls out" of the language design and execution model.
Because Erlang is different in several subtle and not-so-subtle ways from "regular" languages, it's really hard to appreciate it all without being immersed in it. Erlang will change the way you think about and structure your code. It should anyway, because it's different. And it's different in ways you probably won't expect.
As an example, a huge thing that's gone away is the need for complex boolean expressions. You know:
((foo == 3 && bar == fah) || !(foo == 2 && (baz == 1 || !snoz)))
I've hardly had to use any logical
ANDs, it's mostly handled by pattern matching, which just seems to do a better job. I didn't expect that, and I'm not completely sure why it is.
And for some reason, the
if expression is broken in Erlang. Don't ask me how it's possible to screw up
ifs but Erlang does it in a way that almost makes it useful, but not quite. But it doesn't even matter, because
case statements with pattern matching is so natural and powerful you'll barely miss
ifs (but you will miss them occasionally).
And it's the same pattern matching that makes it easy for a process to extract the right message out of its message queue, greatly simplifying messaging code. It also makes it easy to detect invariant states and error conditions, meaning problems are identified early before they can propagate and cause further damage.
The point I'm trying to make is there is so much that works differently in Erlang it's hard to appreciate how any one part of it could help you in your situation. You have to try it out, see how the pieces fit, wrap you brain around it, then you'll see how it can be applied to your problems. And how you're problems will change. Some things you can't read about to understand, you have to experience them.
Also, contrary to what I said in my last post, I actually am of the opinion Erlang generally makes for fewer actual bugs, but my own coding efforts haven't been sufficiently tested for me to really judge. But so far it feels solid. We'll see.
Another great comment left by Jeremy Bowers:
The natural temptation is to skirt around the problem, try to avoid the domain, and just sort of hack around and get by. Hence, the dominant threading model of today with shared memory being the primary paradigm, and thread-level memory being the exception, and all the fun locking and race conditions and such that ensue. And you feel like you've accomplished something.
It's funny because it's true. Almost any time in an application you add some concurrency it really does feel like a big accomplishment.
But sometimes, if you gird up your loins, bravely attack the problem head-on, take no prisoners, no holds barred, and let the problem domain guide you to another locally-maximal solution, you can end up in a local maximum much higher than the first one.
I've been playing with Erlang myself lately, and I get the feeling that that is where Erlang is; by embracing multithreadedness instead of cowering from it, and following it where it goes instead of trying to drive it, it ends up with an exceptionally powerful approach to software. I regret to say I don't think Erlang is going to ride its way up to the top in its present form (short form: too foreign for most people to cotton too due to its functional heritage, but I think that's the programmer's problem, not Erlang's), but I am fairly certain that in 10 years, something very like Erlang is going to be one of the dominant languages of the day because of how we'll all be running 128-core machines on our laptops and how naturally Erlang extends into that environment. (In fact I'm almost not certain how this statement could be wrong...)
Yup yup yup. I also think Erlang has just enough weirdness that it won't ever become "mainstream", but will influence a lot of languages in the years to come (the Frank Zappa of programming languages).
Posted June 15, 2006 1:39 AM