eric | Feb. 25, 2020, 3:32 p.m.
Comments to the book "Learn You Some Erlang For Great Good" by Fred Hébert, Chapter 4 - Types (or lack thereof). Pattern matching is much easier to achieve in Erlang than in many other languages, but the syntax takes some time to get used to. Instead of if-else or similar conditional branching, in Erlang, you simply use functional declarations with a pattern. Learning goals: Understand how Erlang's "crash first" philosophy and always accounting for errors works with dynamical typing to keep things safe. Challenges: See how the lack of static types does not mean that Erlang code is error-prone.
This chapter is about how Erlang handles types. It is easy or difficult, depending on if you choose to get into static types or not. Here I won be getting into static types in Erlang, because it is too complex at this stage and it is also not needed to make perfectly functional Erlang programs. Static types, Dialyzer and typer will be added as separate chapters in the Advanced-section on this site. Stay tuned. Note that the static types-part of the chapter in Learn You Some Erlang For Great Good is outdated and partially wrong (because of updates in R13B04 onwards).
Erlang is both dynamically typed and strongly typed. Dynamically typed means that the type is inferred by Erlang; there is no need to specify the type. Many programmers see static typing as an important part of code safety. However, Erlang has it own way of ensuring this, through a "crash first" and "program for what you know" philosophy:
Erlang uses a strategy where it is assumed that errors will happen anyway and makes sure to cover these cases: Erlang's dynamic type system is not a barrier to reliability and safety of programs.
Strongly typed means that Erlang does not do implicit type conversion between terms; it will throw an error instead. You need to explicitly state all type conversions. Examples:
1> X = 10 + "1" . ** exception error: an error occurred when evaluating an arithmetic expression in operator +/2 called as 10 + "1" 2> Y = 10 + erlang:list_to_integer("1") . 11
In the last example, we use an explicit type conversion list_to_integer. Type conversions are done by so-called built-in functions (BIFs) in the erlang module. All the conversion BIFs are (as per ERTS Reference Manual V.8.1):
* The second argument is an options list. Passing in [safe] will ensure that the binary won't be decoded if it contains unknown atoms or anonymous functions.
** Should be used for testing purposes only.
We have already looked at guards and how they can be used when pure pattern matching falls short, for instance, when using ranges. So how do we use guards to test for a given type? We use type test BIFs. All the type test BIFs that can be used in guard expressions are (as per ERTS Reference Manual V.8.1):
|is_pid/1||is_port/1||is_record/2 *||is_record/3 **|
* Allowed in guard tests, if RecordTag is a literal atom.
** Allowed in guard tests if RecordTag is a literal atom and Size is a literal integer.
Note that is_alive/1, is_process_alive/1 are not type tests, nor are they allowed in guards.
Erldocs - An alternative to the official sites.
Erlang Patterns - A collection of Erlang patterns
Rebar3 - A build tool for Erlang that makes it easy to compile and test Erlang applications and releases.
Erlang mailing lists and forums
The Google group Erlang Programming
Erlang on Stack Exchange
Erlang on Freenode - Use #Erlang
Erlang on Slack
"Learn You Some Erlang For Great Good", by Fred Hebert
"Programming Erlang", by Joe Armstrong
The Zen of Erlang, by Fred Hebert. A partly practical, partly philosophical take on Erlang.
Ericsson's coding standard for Erlang - Programming rules and conventions.
Getting started with Erlang using IntelliJ IDEA (including Rebar3).
Experienced dev and PM. Data science, DataOps, Python and R. DevOps, Linux, clean code and agile. 10+ years working remotely. Polyglot. Startup experience.