Erlang Camp Amsterdam: why you should follow it and getting started with Erlang and Axiom

Introduction

The last two days of August there is a 2 day Erlang course in Amsterdam. One of the most incredible things, is that there is a low cost offer sponsored by Spil games that reduces the price to 55€ for both days; talk about a steal!!

First things first: why should you follow a camp on Erlang?

People who know me in person know that I am an avid fan of Erlang, even though I have only done some very small experiments with it.

Even if you are not planning on developing something in Erlang, you should at least try to grasp the basic concepts!!

You want to know why? Here is why:

Opinionated - but proven - architecture

Today's world of always connected web-apps, is much more similar to the telecom world then the web-apps from a few decades ago. People are currently continuously connected, and they expect almost-immediate responses.

As you can imagine, designing a proper software architecture for this takes a lot of time, but this is one of the parts where Erlang excels:

All the time you spend on building infrastructure for a well-designed application can be simply skipped. Erlang offers a very opinionated but proven tech stack that implements this for you out of the box, including things like messaging, local and distributed persistent storage, supervisor processes, ...

Next to this it also does not care on which machine a process runs;there is no extra implementation cost to run your process on multiple machines. (cloud anyone?)

The actor model

Actors are the "mode du jour" when it comes down to development buzzwords, but they happen to work pretty good in distributed environments. The whole Erlang infrastructure is built around processes communicating to each other with mailboxes per process, and they to offer selective receives and timeouts in a pretty straightforward way.

Because the VM is custom built for this platform, it has some extra things other VM's do not have, like soft-realtime processing and per-process garbage collection. The VM is optimized for the actor model.

Productivity

Erlang has a bit of a quirky syntax due to it's origins (Prolog), so it takes some getting used to the difference between ending a line with a semicolon, a comma or a dot. While this might seem odd, it comes naturally after a while, but it takes some persistence.

Next to this, Erlang has pattern matching (a little bit comparable to polymorphism in OO languages, but it even goes way further then that).

They even have something like generics using behavior.

Another odd thing for someone coming from an imperative programmer's world is the advice of not using if statements. While this might sound really odd, it does offer a lot of advantages (i.e. the whole explicit vs implicit discussion).

All these and other things might sound a bit odd, but they allow you to focus your code on business behavior, and infrastructure is just there to use it, without interfering with your code.

Typical stories from multiple resources show that code is reduced to about a third when converting to Erlang.

Others

There are numerous other reasons why to opt for Erlang in certain cases, here are some resources:

Ok, you convinced me, but how do you get started on this?

Quite simple: unicorns & fairydust. Or, if those are not available, there is another way (it took me a while to figure all of this out, but once you know it, it is quite simple):

Install prerequisites

First we need some kind of a package manager. As this example is currently in Windows, I will start by installing a package manager: Chocolatey.

Open a command window as an administrator, and type the following (copied from the chocolatey website):

@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%systemdrive%\chocolatey\bin

Close the command window, and open it again, you will now be able to install applications using the command line; we will start by installing git and Erlang from the command line:

cinst git.install
cinst erlang

You now should have both git and Erlang installed. If I am not mistaken git should be available from the command line right now

But we also need to make the Erlang binaries available on the command line. You can do this by setting the path in the windows settings, or just for this one command window.

As I am trying to keep this post short, I will just opt for the latter; in the command window you should type the following:

set path=%path%;c:\Program Files\erl5.10.1\bin

Where path should of course match your install path.

Get a package manager

As most languages, Erlang has a package manager; I currently opt for rebar.

Go to a path where you want to put your code; type the following:

git clone https://github.com/basho/rebar.git

This should provide you the source, but also the binaries to the rebar package manager.

Tot test whether it works, just type rebar -c and it should show you the following output:

E:\Dev\erlang\rebar>rebar -c

clean Clean compile Compile sources

escriptize Generate escript archive

create template= [var=foo,…] Create skel based on template and vars create-app [appid=myapp] Create simple app skel create-node [nodeid=mynode] Create simple node skel list-templates List available templates

doc Generate Erlang program documentation

check-deps Display to be fetched dependencies get-deps Fetch dependencies update-deps Update fetched dependencies —-><8——- cut for brevity

Let's build a POC helloworld first

Create the folder where you want your app to reside, and copy the file rebar. and rebar.cmd into this folder.

First we are going to generate an app; this should create a subfolder src with 3 files in it.

E:\Dev\erlang\erlcdemo>rebar create-app appid=helloworld
==> erlcdemo (create-app)
Writing src/helloworld.app.src
Writing src/helloworld_app.erl
Writing src/helloworld_sup.erl

For now we will ignore the *app and *sup files, but create another file under the src folder, named helloworld.erl. This should be the content:

-module(helloworld).
-compile(export_all).
 
hi() ->
hi("stranger").
 
hi("Tom") ->
hi("silly sod");
 
hi(Who) ->
io:format("Hello ~s!~n",[Who]).

We will now open Erlang, compile the code and test it (without rebar). this is what it looks like:

E:\Dev\erlang\erlcdemo\src>erl
Eshell V5.10.1  (abort with ^G)
1> c(helloworld).
{ok,helloworld}
2> helloworld:hi().
Hello stranger!
ok
3> helloworld:hi("Bart").
Hello Bart!
ok
4> helloworld:hi("Tom").
Hello silly sod!
ok
5> q().
ok
6>
E:\Dev\erlang\erlcdemo\src>

Ok, so this works, but it is not very impressive, so ...

Let's convert the POC into a web app!

Get a web framework

We will use rebar to download the axiom framework, which is a bit like Sinatra for Erlang.

We create a file in the root folder of our solution called rebar.config:

E:\Dev\erlang\erlcdemo>copy con rebar.config
{lib_dirs, ["deps"]}.
{deps, [
    {'axiom', "0.1.0", {git, "git://github.com/tsujigiri/axiom.git", {tag, "v0.1.0"}}}
]}.
^Z
        1 file(s) copied.

(You can also use notepad to create this file, but I wanted to show the path it was created in.)

Next, load all the dependencies:

E:\Dev\erlang\erlcdemo>rebar get-deps
==> erlcdemo (get-deps)
Pulling axiom from {git,"git://github.com/tsujigiri/axiom.git",{tag,"v0.1.0"}}
Cloning into 'axiom'...
==> axiom (get-deps)
Pulling cowboy from {git,"git://github.com/extend/cowboy.git",{tag,"0.8.3"}}
Cloning into 'cowboy'...
Pulling erlydtl from {git,"git://github.com/evanmiller/erlydtl.git","dda4db0"}
Cloning into 'erlydtl'...
Pulling mimetypes from {git,"git://github.com/spawngrid/mimetypes.git",
                            {tag,"1.0"}}
Cloning into 'mimetypes'...
==> cowboy (get-deps)
Pulling ranch from {git,"git://github.com/extend/ranch.git","0.8.0"}
Cloning into 'ranch'...
==> ranch (get-deps)
==> erlydtl (get-deps)
==> mimetypes (get-deps)

E:\Dev\erlang\erlcdemo>

Now we have to convert our code into a web app: open the src\helloworld.erl-file, and change it to the following:

-module(helloworld).
-compile(export_all).
 
start() ->
application:start(crypto),
application:start(ranch),
application:start(cowboy),
axiom:start(?MODULE).
 
% Hi url without parameter
handle(<<"GET">>, [<<"hi">>], _Req) ->
hi();
 
% Hi url with parameter
handle(<<"GET">>, [<<"hi">>, Name], _Req) ->
hi(Name).
 
hi() ->
hi("stranger").
 
hi(<<"Tom">>) ->
hi("silly sod");
 
hi(Who) ->
FormattedList = io_lib:format("<h1>Hello ~s!</h1>~n",[Who]),
erlang:iolist_to_binary(FormattedList).

Then we can compile everything; go to the root folder of your solution, and do this:

E:\Dev\erlang\erlcdemo>rebar compile
==> ranch (compile)
Compiled src/ranch_protocol.erl
Compiled src/ranch_transport.erl
Compiled src/ranch_acceptor.erl
Compiled src/ranch_acceptors_sup.erl
Compiled src/ranch_app.erl
Compiled src/ranch_listener_sup.erl
Compiled src/ranch.erl
Compiled src/ranch_conns_sup.erl
Compiled src/ranch_sup.erl
Compiled src/ranch_server.erl
Compiled src/ranch_tcp.erl
Compiled src/ranch_ssl.erl
==> cowboy (compile)
Compiled src/cowboy_http_handler.erl
Compiled src/cowboy_loop_handler.erl
----><8------- cut for brevity

If everything compiled well, we are good to go, let us run the web app:

E:\Dev\erlang\erlcdemo>erl -pa ebin deps\crypto\ebin deps\ranch\ebin deps\cowboy\ebin deps\axiom\ebin deps\erlydtl\ebin
Eshell V5.10.1  (abort with ^G)
1> helloworld:start().
{ok,<0.49.0>}
2>

That's it; now surf to https://localhost:7654/ and you should get a 404 / Not found.

Next, surf to https://localhost:7654/hi and you should get Hello stranger! as an answer.

Next, try https://localhost:7654/hi/Bart and https://localhost:7654/hi/Tom, and they should all work...

If you change the helloworld.erl file, there is no need to quit Erlang, just compile it from the shell, and code will hot-load:

E:\Dev\erlang\erlcdemo>erl -pa ebin deps\crypto\ebin deps\ranch\ebin deps\cowboy\ebin deps\axiom\ebin deps\erlydtl\ebin
Eshell V5.10.1  (abort with ^G)
1> helloworld:start().
{ok,<0.49.0>}
2> c("src/helloworld").
{ok,helloworld}
3>

Probably the next thing to do would be using proper OTP behaviour, but I assume this will make this post to big, so I will call it a day for now.

Conclusion

Well, we only touched the top of the iceberg here, but the main idea of this post is to get you interested in Erlang, and show you how easy it is to get started if you know how to do it.

Erlang really shines in always available/connected/distributed systems.

And, if your interest is triggered, might I suggest you to join me on the Erlang Camp course in Amsterdam, as this is true value for the buck.

Laters!

Tom

 

PS: a big thank you goes out to @helgeraush (the author of the axiom framework) for reviewing this post!