Why Erlang?

by Brujo Benavides

Who's Brujo?

Erlang Dev for 15 years
Erlang Trainer
Open-Source Maintainer
about.me/elbrujohalcon

The ones you know

 

The benefits you already heard about…

Scalability

 

What runs with 10 users,

can run with 10M users!

Concurrency

 

It's ideal for soft real-time systems.

Fault Tolerance

 

Let it crash!

Hot Code Updates

 

You can update your systems with no stopping time.

Praise 👍

  • Scalability
  • Concurrency
  • Fault Tolerance
  • Hot Code Updates

Critics 👎

  • No Types
  • Hard to Learn
  • Slow for Math
  • No IDE

The Unsung Benefits of the Erlang Ecosystem


words.erl
-module words.
words.erl
-module words.

-export [test/0].

test() ->
  true = words:is_palindrome(""),
  true = words:is_palindrome("a"),
  true = words:is_palindrome("aa"),
  true = words:is_palindrome("aba"),
  false = words:is_palindrome("ab"),
  false = words:is_palindrome("abca"),
  '✅'.
words.erl
-module words.

-export [test/0].

test() ->
  true = words:is_palindrome(""),
  true = words:is_palindrome("a"),
  true = words:is_palindrome("aa"),
  true = words:is_palindrome("aba"),
  false = words:is_palindrome("ab"),
  false = words:is_palindrome("abca"),
  '✅'.
words.erl
1> {ok, words} = c(words), words:test().
** exception error:
    undefined function words:is_palindrome/1
     in function  words:test/0
      (words.erl, line 6)
2>

words.erl
-module words.

-export [test/0, is_palindrome/1].

test() ->
	…


is_palindrome("") -> true;
is_palindrome([_]) -> true;
is_palindrome([First | Rest]) ->
    [Last | Others] = lists:reverse(Rest),
    First == Last andalso
    	is_palindrome(Others).

words.erl
-module words.

-export [test/0, is_palindrome/1].

test() ->
	…


is_palindrome("") -> true;
words.erl
-module words.

-export [test/0, is_palindrome/1].

test() ->
	…


is_palindrome("") -> true;
is_palindrome([_]) -> true;

words.erl
-module words.

-export [test/0, is_palindrome/1].

test() ->
	…


is_palindrome("") -> true;
is_palindrome([_]) -> true;
is_palindrome([First | Rest]) ->

words.erl
-module words.

-export [test/0, is_palindrome/1].

test() ->
	…


is_palindrome("") -> true;
is_palindrome([_]) -> true;
is_palindrome([First | Rest]) ->
    [Last | Others] = lists:reverse(Rest),
words.erl
-module words.

-export [test/0, is_palindrome/1].

test() ->
	…


is_palindrome("") -> true;
is_palindrome([_]) -> true;
is_palindrome([First | Rest]) ->
    [Last | Others] = lists:reverse(Rest),
    First == Last andalso

words.erl
-module words.

-export [test/0, is_palindrome/1].

test() ->
	…


is_palindrome("") -> true;
is_palindrome([_]) -> true;
is_palindrome([First | Rest]) ->
    [Last | Others] = lists:reverse(Rest),
    First == Last andalso
    	is_palindrome(Others).

words.erl
15> i().
Pid                   Initial Call                          Heap     Reds Msgs
Registered            Current Function                     Stack
<0.0.0>               erl_init:start/2                       987     5342    0
init                  init:loop/1                              3
<0.1.0>               erts_code_purger:start/0                 1       11    0
erts_code_purger      erlang:hibernate/3                       1
<0.2.0>               erts_literal_area_collector:start        1       10    0
                      erlang:hibernate/3                       1
<0.3.0>               erts_dirty_process_signal_handler      233      722    0
                      erts_dirty_process_signal_handler        3
<0.4.0>               erts_dirty_process_signal_handler      233        9    0
                      erts_dirty_process_signal_handler        3
<0.5.0>               erts_dirty_process_signal_handler      233        9    0
                      erts_dirty_process_signal_handler        3
<0.6.0>               prim_file:start/0                      233        8    0
                      prim_file:helper_loop/0                  2
<0.7.0>               socket_registry:start/0                233       10    0
socket_registry       socket_registry:loop/1                   5
<0.10.0>              erlang:apply/2                        6772    54663    0
erl_prim_loader       erl_prim_loader:loop/3                   7
<0.42.0>              logger_server:init/1                   987      668    0
logger                gen_server:loop/7                       12
<0.44.0>              erlang:apply/2                        1598     1177    0
application_controlle gen_server:loop/7                        8
<0.46.0>              application_master:init/4              376       45    0
                      application_master:main_loop/2           8
<0.47.0>              application_master:start_it/4          233      493    0
                      application_master:loop_it/4             7
<0.49.0>              supervisor:kernel/1                    987     2736    0
more (y/n)? (y)
16> erlang:process_info(<0.44.0>).
[{registered_name,application_controller},
 {current_function,{gen_server,loop,7}},
 {initial_call,{erlang,apply,2}},
 {status,waiting},
 {message_queue_len,0},
 {links,[<0.46.0>,<0.0.0>]},
 {dictionary,[{'$initial_call',{application_controller,start, 1}},
              {'$ancestors',[<0.9.0>]}]},
 {trap_exit,true},
 {error_handler,error_handler},
 {priority,normal},
 {group_leader,<0.64.0>},
 {total_heap_size,2589},
 {heap_size,1598},
 {stack_size,8},
 {reductions,1179},
 {garbage_collection,[{max_heap_size,
 						#{error_logger => true,
                          kill => true,
                          size => 0}},
                      {min_bin_vheap_size,46422},
                      {min_heap_size,233},
                      {fullsweep_after,65535},
                      {minor_gcs,4}]},
 {suspending,[]}]
17> sys:get_status(<0.44.0>).
{status,<0.44.0>,
        {module,gen_server},
        [[{'$initial_call',{application_controller,start,1}},
          {'$ancestors',[<0.9.0>]}],
         running,<0.9.0>,[],
         [{header,"Status for generic server application_controller"},
          {data,[{"Status",running},
                 {"Parent",<0.9.0>},
                 {"Logged events",[]}]},
          {data,[{"State",
                  {state,[],[],[],
                         [{stdlib,undefined},{kernel,<0.46.0>}],
                         [],
                         [{stdlib,permanent},{kernel,permanent}],
                         [],[]}}]}]]}

Tracing

  • dbg, trace, etc. (by the OTP Team)
  • Recon (by Fred Hebert)
  • Redbug (by Mats Cronqvist)
  • Rexbug (by Jacek Królikowski)
  • WombatOAM (by Erlang Solutions)

Elixir / Gleam

Erlang

Erlang

TDD-Ready

Declarativeness

Observability

Tooling

TDD-Ready

Declarativeness

Observability

Tooling

  • Multi-platform / JIT
  • It's mostly just back-end
    • i.e., no fashion consultancy :)
  • Many problems alredy solved
    • GC… what's that thing?
    • Distributed systems… of course!
    • Protocol parsing… easy!
  • Whole stack built-in
    • Database
    • Web Server
    • File System Management

Thanks!

Contact me via email or Twitter/X if you have any questions.

 

Or you can find me anywhere as @elbrujohalcon

https://slides.com/elbrujohalcon/why-erlang

Why Erlang? @ the functional lab

By Brujo Benavides

Why Erlang? @ the functional lab

The Unsung benefits of the Erlang Ecosystem

  • 87