Articles

Erlang tutorial for PHP developers


This article is intended for PHP developers that want to understand and start learning and coding Erlang applications.

I'll try to point out the differences between these two distant worlds from a general perspective first, then slowly dive into the gory details more and more as we need to.

Hopefully, you will be able to continue your journey as an Erlanger from a more solid base, you should be able to ask the right questions to learn more, have a global understanding of how Erlang works, and pinpoint your next learning steps according to what is more interesting for you, so please bear with me until the end :)

What is Erlang and what is OTP?

Erlang is a Functional programming language, designed by Ericsson.

OTP (Open Telecom Platform) is the ERTS (Erlang Run-Time System) plus a set of libraries, reusable components, and design principles for Erlang programs and applications.

So when talking about Erlang and/or OTP, we're actually referring to both of them, that is Erlang/OTP.

Programming paradigms of PHP and Erlang

One of the biggest differences between both languages is that PHP can be used as an OOP language and also for Procedural programming. PHP feels closer to how C and Java work (...in some sense).

On the other hand, Erlang is a Functional language, and can be compared (again, in some sense) to how Haskell, LISP, and the like work.

Processes and concurrent programming in PHP and Erlang

Erlang supports concurrent and distributed programming, and implements the Actor Model to provide communication and isolation between processes. This provides the needed tools to write horizontally scalable applications out of the box.

PHP does not have processes, isolation, concurrent or distributed programming, and things like that. The only way to scale a PHP application is vertically (unless some kind of microservice architecture is used).

PHP REPL and the Erlang shell

You can invoke the PHP REPL by executing php -a. On the other hand, Erlang has a full shell that provides many utilities to interact with the local (or remote) Erlang nodes. You can do this by just running erl.

Mindblowing part: Whenever you run any of the PHP SAPIs (CGI, CLI, etc) you are calling the Zend Engine and running the VM that will interpret your code and do whatever thing your program is supposed to do, it will finish with your code and die. But when you execute the erlc command, you are actually starting an Erlang node!. Remember: Erlang will always run a distributed environment, even if that means to be the only node in a cluster.

State and behavior in PHP and Erlang

In PHP you can encapsulate state in the instance variables of your objects and behavior in methods.

In Erlang, state is kept in processes, and behavior in functions wrapped inside modules.

PHP and Erlang virtual machines

PHP uses the Zend Engine, and Erlang uses the BEAM.

The Zend Engine provides a VM with a set of limited features when compared to the BEAM. The Zend Engine has a single execution thread that can crash (and thus, crashing your program completely) and only provides the very basic set of features needed for an OOP language (exceptions, classes, flow control, etc).

The BEAM looks more like an OS (processes, isolation, supervision trees, concurrency, scheduling, time control, messaging between processes, etc), see this StackOverflow answer by Robert Virding.

Also, when coding in Erlang you get a concurrent and distributed environment for free that you can take advantge of :)

Coding workflow in Erlang and PHP

When writing PHP programs, it's enough to create a file, write some code, and then run it via the PHP CLI SAPI, or through a web server like Apache, Nginx, or Lighttpd as a CGI or FastCGI script.

In Erlang, after writing your code, you have to compile it first by using erlc or from the erlang shell by using the c/1, c/2, or c/3 functions. The compiled code then needs to be "loaded" through code:load_file/1 or when loading your OTP application.

PHP does something similar, actually. When invoking a script (it doesn't matter through wich SAPI), it will be automatically compiled to Zend virtual machine opcodes and then the VM will run the code. Sometimes that compiled code will be cached to gain speed the next time it's used.

PHP and Erlang applications

PHP does not have "applications" per se. You just write your source files and then somehow run them. There are many frameworks that provide the concept of "application" (Zend, Laravel, Symfony, Yii, and many more).

In Erlang, there are Erlang/OTP Applications that can be started/stopped/monitored and maintained as a whole, they encapsulate one or more modules, and can have several properties (like dependencies, etc).

Source file extension for PHP and Erlang

PHP files have the .PHP extension (sometimes web applications make use of the .PHTML extension).

Erlang files have the .ERL extension, and .BEAM files are generated by the compiler after compiling each source file.

Source file names in PHP and Erlang

In PHP you can choose any file name for your code, and this means that you can write any number of classes, functions, and standalone code in it.

Note that you should most likely be following the PSR-4 standard, using specific names and directories for your files depending on the namespace and the names of the classes, and things like that.

In any case, in Erlang the name of the file must match the module name declared in it. For example, the following file must be named "sample_module.erl" because it's declaring a module named "sample_module":

Source file structure in PHP and Erlang

In PHP there is not much structure in a source file besides using the PHP tags to delimit the php code that need to be interpreted.

In Erlang, every source file contains only one module. Each module has it's name as the first line, this is followed by the module attributes, and then the function declaration follow. Take a look at this example erlang module from the erl_vcron project.

Code visibility in PHP and Erlang

PHP make use of the keywords public, protected, and private. Erlang by default makes every function in a module private. To make it publicly available, you can use the export module attribute.

Variables in PHP and Erlang

In PHP, variables can change their value by using "=", called the assignment operator.

In Erlang, = is actually the Match Operator, this means that variables will first be tested for equality, and then assigned a value if they are not bound to any, failing if the value does not match the current bounded one. For example:

In this case there is an unbound variable (i.e: one that is not defined yet) called "X", being tested against the value "1". Because "X" does not exist yet, it is bound to the value 1, and from then on X can be used. Then, "X" is again trying to be matched against the value 2, because X now exists but it's bound to the value 1, the match fails and this is an error that will make your program crash (and that's perfectly fine, too :)).

See this StackOverflow question about the pattern matching subject.

This is called "pattern matching" and is one of the key components of Erlang, and one its most powerful features.

PHP and Erlang data types

PHP has arrays, objects, strings, etc. Erlang has:

  • Atoms: These are similar to Ruby symbols, and they are useful to represent constants and keywords in your code. They start with a lowercase letter (or are enclosed in ' if they start with an uppercase letter). Variables will always start with an uppercase letter.
  • Lists: A list of items, similar to an array in PHP, although you can't directly access an item by its index in the list out of the box.
  • Boolean: Boolean values are actually represented by the atoms true and false and they are not boolean values per se.
  • Maps: Analogous to an associative array in PHP.
  • Functions: Erlang treat functions as first class citizens, this means that you can send and receive functions just like any other data type, this is similar to how PHP Callables work.
  • Tuples: Groups a number (limited, fixed number of) of terms together.
  • Records: They are implemented as tuples, actually, they have named members and can be used to store values like a struct in C.
  • Binaries: Represent a number of bits.
  • Pids: A process identifier.
  • Numbers: Integers and floats.
  • References: A unique term in the ERTS.

Here are some examples:

Your first Erlang module

Open your terminal and create a file test.erl with the following code:

Now let's compile it and run it in the erlang shell:

Erlang and PHP project and package managers

It's most likely that you're using composer in your PHP project to handle dependencies and other project-related things.

In Erlang, Rebar is the preferred way to manage projects and dependencies, closely followed by erlang.mk.

What's next

From now on, you have a very basic but clear idea of what is Erlang/OTP, and its main differences from PHP and other languages. This is where the real thing starts, and the following references will help you out in writing code: