Introduction to Elixir - Functions, Built-in and Complex Types - Part Two
What Will I Learn?
- How to create and use Functions in Elixir
- How to use the Erlang built in types such as Ranges, Keyword Lists, MapSet, DateTime, and IOList
- How to use Closure Functions to shallow copy variables
- How to create anonymous functions and bind them to variables
- How to use the
defmoduleconstructs and the Observer GUI
- Elixir v1.8 requires Erlang 20.0 or later
OS Support for Elixir and Phoenix:
- Mac OSx
- Unix and Linux
- Raspberry Pi
- Some basic Programming Knowledge
- An Elixir installation
- VsCode or any other Text Editor
Resources for Elixir and Phoenix:
- Elixir Website: https://elixir-lang.org
- Elixir Installation Instructions: https://elixir-lang.org/install.html
- Awesome Elixir Github: https://github.com/h4cc/awesome-elixir
- Phoenix Website: https://phoenixframework.org/
- Phoenix Installation Instructions: https://hexdocs.pm/phoenix/installation.html
- Elixir Documentation: https://elixir-lang.org/docs.html
- Phoenix Documentation: https://hexdocs.pm/phoenix/Phoenix.html
- LiveView Github Repository: https://github.com/phoenixframework/phoenix_live_view
- Elixir Image: https://elixir-lang.org
In this Elixir Video Tutorial, we continue on from the first video and expand upon our knowledge of the Types available in the language. We look at the Complex and Builtin types such as the Range type, the MapSet type, the Process ID type, IOLists and DateTime types. We also look at the Function type and it's many first class features in the Elixir Language.
Builtin and Complex Types in the BEAM
Despite being a Dynamic language, Elixir has a large amount of primitive and complex types built into it. All of these Complex Types are types that were coupled into the BEAM system for various reasons. For instance, the reference type is a unique piece of information which is guaranteed to be unique so long as the BEAM instance continues to run. There is also the Process ID type or
pid which is used to identify Erlang processes; a main principle of the Actor Model. Other Higher Level types include the Range type, the Keyword List type, the MapSet type, Date and Time types and IO Lists.
The image above features many of these Complex Types and operators associated with them. At the top we have a basic range type; defined between 1 and 5 using double dots
... The range is an abstraction that gives us a memory efficient way of representing a range of numbers. Keyword lists are a special type of list composed of two element tuples where the first element in each tuple is an atom. These are often used as small size key value structures. The MapSet is similar to the HashSet from other languages; its a store of unique values but it doesn't preserve the ordering of each value. The Date and Time types are fairly self explanatory as types that define dates and times as well as both combined. Finally, we have IO Lists; which are a special type of list used in Input/Output operations. IO Lists are extremely useful for building streams of bytes and they are much more efficient then normal list structures due to their nested nature.
Functions and Function Types in Elixir
At its core, Elixir is a functional programming language. Naturally, this means that Functions are first class types in Elixir. You can bind functions to variables, pass them to other functions and even return them from other functions. This gives rise to the concept of Lambda functions and Closures as well as Anonymous functions and named functions.
This image shows some basic examples of the different types of functions in Elixir. At the top we have a Module defined as
Playground. Inside of it is a single line function called
area_of_circle and below that is a function called
area. These two functions are identical to one another except
area_of_circle uses syntactic sugar to be defined on a single line. Outside of the Module, we have a few anonymous functions. There are two Anonymous functions, one bound to the variable
s and another one bound to
s function just takes a variable and multiplies itself by itself. the function in
x takes a single argument and calls the
IO.puts/1 function with it. Down below is an example of passing a function to another function. With the
Enum.each/2 function we can apply a callback function to each value in an enumerable. In this case we are applying the
x function to each element of a list. At the very bottom we have a function called
lambda which is a closure. It uses a variable defined outside of the function body and by doing so, it makes a shallow copy of this variable. This means that even should the variable's data be rebound, the copy attached to the function will not.
Full Github Source Code can be found here: https://github.com/tensor-programming/intro-to-elixir/tree/tensor-programming-part-2