Why Erlang?

A straight cut-and-paste from erlang-questions - it pretty much sez. it all, and very eloquently at that

Anything can be done in any language, so the technical answer is "nothing".
But the spirit of the question begs for an answer, especially in a company
situation with deadlines.

My company does mostly business data systems and custom extensions to certain
products of ours. Originally we used a mix of Python (probably 70%), PL/pgSQL
(maybe 10%), Guile/Scheme (probably around 10%), C (5%ish) and a smattering of
Bash, Perl, Scala or Java, etc. where necessary. I am extremely familiar with
Python and Guile, and between those two a one-dimensional solution to any
conceivable problem can be reduced to triviality. They are great languages.
They have great libraries. They tie into the rest of the *nix world smoothly.
Super tools, *vastly* superior in every way (for us) than more prolific tools
such as Java.

But when it came time for us to deal with some new feature requests -- like
internal chat + whiteboard utilities that tie directly into company
dashboards, message systems that can't go down (outside of an earthquake or
something), and meshing Android, iOS, Windows and Linux native clients
together... Doing everything in the web wasn't cutting it for various reasons
and most importantly: The way we wanted to solve our problems required that we
write a service management layer.

A service management system is *not* something you just do over the weekend.
Its a big deal. The APIs to it from various languages can be wonderful or they
can infect every subordinate project with cancer. This stuff just isn't easy.

Luckily, pretty early on in the design phase I started looking around at
alternatives and remembered Erlang and how easy it was to do certain things. I
can back to it, toyed with it a bit, and in a few weeks wrote stub examples of
the sort of things we wanted to do the way we had always wished were possible.
And I didn't have to write any service layer. The Erlang environment is its
own service layer. We *could* have been like Google and written our own at
great expense, but it turns out that's simply not necessary.

We still do a lot of Python (client-side), Scala (Android) and Guile
(internally), but almost the entire world of business logic, network services,
messaging systems, and just about all other back-ends for anything that
involves the network is either in Erlang or will soon be. Its just a lot
easier.

Why?

Binaries: I can't explain how much easier it is to deal with binaries in
Erlang than C. This alone is reason enough to swap all your network code. In
particular, if you deal with sockets at all, Erlang is probably the right
tool.

Sockets: In addition to the comments above about handling the data once you've
received it, writing "from scratch" socket handling code in Erlang is easier
than using any socket libraries I've dealt with. Especially with regard to
cleanup when something goes wrong.

ASN.1: Cryptographically validated (signed, encrypted, whatever) data
structures are usually easiest in ASN.1, and Erlang has *great* facilities
here as well.

"Let it crash": Its not about being lazy or inviting instability, its about
writing code that only deals with the problem, instead of inventing 50 other
problems in the form of data validation everywhere. Here your error code and
your core problem-solving code are clearly separated from one another, and
that means you can identify and factor out similarities in them independent of
one another. Once we understood this, our code got better and much smaller.

Supervision: Automatic restarts to a known state. Wow. Limiting how bad things
can get is amazingly powerful. But you won't realize this until you screw
something up really bad, and then realize how much worse it would have been
without a supervision tree helping you.

Inspection: IBM's JVM has some pretty amazing tools for inspecting itself
while running and great crash and debug tools. Awesome stuff. Erlang's are even
better. This takes time to learn your way around, though, at least it has for
me. At the very simplest end of things, though, go start an Erlang shell and
type "observer:start()". If you guys write any server software at all, doing
this during a presentation should be convincing enough to get other folks in
your company curious (might not be strong enough to sell them on it unless you
demonstrate monitoring of remote notes that are doing interesting things live,
but it should definitely get them interested).

Messaging is not RPC: This is probably not an idea you can easily explain in a
quick presentation to management, but the way Erlang enforces this distinction
is important. It means you don't have to change the way you think when you're
messaging between Erlang processes and when you're networking messaging over
sockets to non-Erlang things. Because binary data is easy in Erlang the
difference between network traffic and process-process traffic (which may involve
the network, but its invisible to you) melts away because you don't get
distracted for weeks writing heavy duty network code and then turning back to
your comparatively trivial problem.

Dialyzer: I haven't seen a better middleground solution to type checking in a
dynamically typed language than this. The real utility of it comes once you
learn to concentrate your side-effecty code in small, specific areas, and mostly
write purely functional code. You can't "verify" your programs, maybe, but you
can verify a function at a time and have a very high degree of confidence in
most of your code -- and almost never have to revisit large parts of it in
maintenance.

...and a long list of other things. Oh yeah, concurrency... its really easy in
Erlang, but I assume you've heard.

What can you *do* in it? You can avoid writing your own service framework. All
the applications frameworks, service layer frameworks, and nearly anything
else with the word "framework" in it are attempts to re-write OTP in other
languages. We were doing this in Python without realizing it.

Handling binaries ("How can we make validation easy?"), handling sockets ("how
can we make this easy?"), segregating failures ("how should be isolate these
services as processes?"), isolating data ("where do we need to deep copy to
make sure we're not screwing ourselves elsewhere?"), restarting components
("we need a list of services and known states so we can restart stuff when it
dies..."), multi-processing ("what approach to pooling do we need and how
should the processes talk across each other?") and a slew of other service
layer type issues are just non-issues in Erlang. These problems are usually
harder to solve than the business problem that faces you to begin with. Having
that taken care of is great.

So its not about what you can "only do in Erlang", its really more about what
you don't have to do in Erlang.

This is my feeling based on my experience dealing with business software. I
don't know what your case looks like, but for us it eliminated the need for a
whole category of work, and that was a *big* win. It didn't eliminate all
other languages, but it gave us the freedom to focus only on the problems
those languages are good for once again.

OTOH, Erlang involves a longish learning process. As your development team
learns you will notice a distinct change in coding style their first few weeks
and a year later. There are several evolutions to understanding the natural
way of solving certain problems in Erlang, and OTP is, in my view, its own
distinct family of Erlang (and usually the right one). In any case, your
early, naive implementations of services in Erlang will be at least as robust
(from an external observer) as "proper" implementations in other languages
would be, so there is no loss there. As you learn, though, things get better.

One parting thought: Erlang's VM can be used by several languages. My personal
favorite is Erlang itself, but just like the JVM, Erlang it its own ecosystem
and you don't have to marry just one language. Some types of problems may be
ugly to read in Erlang but quiet elegantly expressed in Elixir or Lisp
Flavored Erlang. I can't stand Java, but Scala is decent and Clojure is
wonderful -- its not about the syntax, its about knowing your platform.

I didn't answer your question or give you a 10-line demonstration of how to
solve the question of Life, the Universe and Everything. Hopefully this gives
you some points to think over when discussing the issue with other developers
and management.

As for encouraging adoption, I recommend you solve a problem in your spare
time that your company has, in Erlang, and demonstrate how easy it is to
maintain compared to whatever the accepted solution being worked on is. That's
a lot safer thing to your management than "throwing money at a new toy, hoping
for a payoff". Incidentally, this approach will yield a lot of insights about
comparative software and personal revelations (perhaps not just to you) about
how your company's leadership thinks and make decisions. If you pick your
battle (and sample problem) wisely, it could turn an adversarial situation
into an all-around win.

(from: "Must convince them! If they say yes I'm happy but panicked to make the
pig fly and they are wary of anything smelling sour. If they say no I'm
frustrated at how short-sighted The Man is and they are worried I'm looking
for an early exit."
to: "If I can demonstrate a better solution that saves them on an ongoing
development cost I look great, they save money, and we all appreciate a new
tool.")

Just my $2.

-Craig


Comments

Popular posts from this blog

Cannonball Tree!