AddThis

Monday, June 24, 2013

This Elixir Comes From What?

Wednesday I'm going to a talk with Dave Thomas (http://en.wikipedia.org/wiki/Dave_Thomas_(programmer)).  It was his "Agile Web Development with Rails" and "Programming Ruby" that started me with my love affair with Ruby and Ruby on Rails.  He's coming to talk about his latest book, "Programming Elixir".  I knew about Elixir from various blogs, but I was never particularly interested in it.  To me, it was just Erlang with Ruby syntax.  But knowing that Dave would be taking about it in a few days, I decided to take another look at it.  On closer inspection Elixir turns out to be very interesting.

First off, what is it?

"Elixir is a functional meta-programming aware language built on top of the Erlang VM. It is a dynamic language with flexible syntax with macros support that leverages Erlang's abilities to build concurrent, distributed, fault-tolerant applications with hot code upgrades."
-- Jose Valim (creator)

In some cases, Elixir will actually run faster than Erlang.  That's pretty damn cool.  And if you're reluctant to try it out, check out this blog post by one of Erlang's creator, Joe Armstrong (http://joearms.github.io/2013/05/31/a-week-with-elixir.html).  If he likes it, there must be something to it.

So while reading the docs, I thought, yep, this is very Rubyish.  But I didn't understand the abstraction that it was doing from Erlang, and that bothered me.  I hadn't done Erlang since college and figured it was time to get back in it, but really learn it this time.  So this post and most likely some future posts are going to be my dip back into Erlang.

Erlang Background
Every language is created with a specific problem in mind to solve.  Erlang started out in the 80s at Ericsson where they were trying to figure out the best way to build systems for their phone systems, switches and such.  They examined over 20 languages and found that none of them totally suited their needs.  So they took what they liked from each language, and with Prolog as it's syntactic inspiration built a new language with the following goals in mind:

1.  Fault tolerance
  The entire system should be stable enough to withstand errors that could occur.
  - Erlang has light-weight processes that are all isolated from one another.  They run in complete isolation which means that if one dies, it does not compromise the entire system.
  - When processes die, they can tell other linked processes that they are dead.  Using something like the OTP (Open Telecom Platform) framework gives you advanced process supervision in the form of trees that delegate responsibility for things like process restarts and restart timeouts.

2.  Non-stop
  They system should never go down nor should you ever have to take the down.  Put simply, they should not stop.
  - The system is fault tolerant so errors will not take the entire system down.
  - Code can be hot swapped in.  This means that you can actually push out newly compiled code while the system is still running.  You also can choose which part of the system you want to deploy the new code to, so you get total control.

3.  Concurrent
  All the processes in an Erlang application are truely concurrent.
  - There is a scheduler per core (with SMP -- Symmetric Multi Processing enabled) that will schedule the work to be done
  - They employ preemptive scheduling so the developer doesn't have to worry about cooperative scheduling.
  - All processes are equal.  This means that no one gets special priority, internal Erlang processes get the same priority as your processes.

4.  Distributed
  Multiple Erlang processes can actually live on different machines and all communicate with each other.  Erlang uses the actor model which means each Erlang process is itself an actor with a mailbox that can receive messages and choose what they do with it.  Each process can additional send messages to any process.  This is a very powerful mechanism and is actually built into the language without having to add any additional modules.

5.  Soft real-time
  Real-time is critical for applications like airplanes where processing in real-time could cost lives.  Erlang was built for phone systems, so real-time is NOT a must.  They are not bound to the same constraints as airplanes.  This is the platform that Erlang was targetted for, and these laxer requirements allows such things as a garbage collector for the Erlang VM.

6.  Prototypeability
  This is a made up word coined by Lennart Ohman used to describe Erlang, but this really just means speed to produce code, or "time to market".  Basically programmer efficiency and speed from inception to production.
    - To allow programmers to work faster, Erlang was designed to be a functional over imperative language, which they believed would allow faster development.
    - Run-time linking.  Linking is done at run time allowing code to be hotswapped in.  This is pretty cool, see the non-stop section.

Erlang has a compiler and that compiled code is then linked at run time and executed.  As I mentioned above, Erlang has a virtual machine, called BEAM, or sometimes EVM.  One of the awesome things about Erlang is that processes are cheap to create and all execute concurrently (to give a little more depth to this, you can actually configure three parameters to help you adjust your concurrency profile.  -P for your process threads, these are actually green threads.  -S which are the scheduler threads, typically one per cpu.  These will schedule the green threads for execution.  -A for your async threads that react to select and poll events).

Erlang isn't all sunshine and rainbows though.  People have complained about the poor performance (notice that performance wasn't one of the goals of the language), the GC isn't that great, and of course the most common criticism is the syntax.  Either way, I'm going to blog about my dive into the language, but for now I'll leave you with the canonical hello world:

Example
Save the following in a file named hello.erl (it must match module name)
-------------------
-module(hello).
-export([hello_world/0]).

hello_world() -> io:fwrite("Hello World\n").
-------------------

Then start Erlang by typing erl at the command prompt.  Then type the following:

c("hello.erl").
hello:hello_world().

Notice the output.
A few things about the syntax:
1.  All lines end in a period.
2.  Module named 'hello', sort of like a namespace.
3.  Export is a method that exposes internal methods to the outside world, sort of like building an api, or declaring public methods.
4.  In the export, notice the brackets, they signify [method name/num of args]
5.  -> is a function definition
6.  c() is a built in Erlang method to compile
7.  module:method() is how you invoke a method.  Notice we called our module 'hello' and method 'hello_world'

And that's pretty much it.  Until next time.

Post a Comment