Functional programming


Elixir is a compiled, functional programming language that is dynamically typed.

But what does that really mean?

Let's break down this statement so we have a better understanding of the constructs of the Elixir language.

Compiled

The code we write inside an Elixir file is not the code that will be executed. There is an intermediary step between writing and executing the code called, "compilation". We write a file with an ex. extension and after it's compiled it will have a .beam extension. These .beam files are executed by the Erlang VM. The point of compilation is to produce an executable chunk of code that can be run with great efficiency. Although compiled and interpreted languages have their inherent strengths and weaknesses, compiled languages are usually faster because the overhead of the translation is incurred just once.

Let's assume we create a file called math.ex that contains some basic arithmetic functions. We can compile the file from the command line with elixirc math.ex . In an iex> shell we can compile the file using c("math.ex") or we could load and compile the file at the same time by starting iex with iex math.ex. Often times you'll be making changes to a file while iex is running and need to recompile. This can be done simply by passing in the name of the module after the "r" command like so,

r Math.

Functional

Elixir applications are composed of many, many functions. There are no classes or objects, which yields a myriad of benefits as you'll learn over time. One of the core principles of software development is making the distinction between data and behavior. With classical programming languages, data and behavior are coupled together. Objects are instantiated and then methods are called on them to alter their state. This behavior leads to code that is tightly coupled and error-prone.

In Elixir, data is immutable. We are forced to separate data and logic. This requires a different perspective, a different approach to writing code. We begin thinking of applications as a series of inputs and outputs. Functions become a means of collecting inputs, performing transformations, and producing outputs. Viewing applications in this way leads to code that is loosely coupled and resistant to errors.

Dynamic

Some languages require that variables and functions specifically declare the type of data they hold or return. These languages are statically typed. Elixir is dynamically typed. Type checking can certainly add benefits to a language. Any data-type errors are caught before runtime, which can certainly be helpful. In the case of JavaScript, a dynamically typed language riddled with flaws and errors, TypeScript shines through as the statically typed and more responsible big brother. However, static type checking would not nearly benefit Elixir as much as it does JavaScript (for reasons outside the scope of this book). Type checking is a good thing, though that does NOT mean being dynamically typed is a bad thing. Also, it's worth noting that Elixir has Type specs, which are used for type checking. This brings Elixir closer to a statically typed language while still remaining dynamic.


It's worth noting Elixir's declarative nature and the benefits thereof.

Erlang and Elixir for Imperative Programmers

"Imperative and functional are the roots of two very distinct programming approaches. If we define it in an oversimplified way, the former tells the computer exactly what to do, step by step. The latter says: here are the high level functions, go calculate the result." - Wolfgang Loder.

The differences between imperative and declarative programming are often summarized as follows: imperative programming is writing how to do something while declarative programming is writing what to do. Keep these differences in mind as we review some background information.

Imperative

Imperative programming came first. It dates back to the "Formula Translation" (FORTRAN) language, a general-purpose language developed by IBM in the 1950's. The programs were written as step-by-step instructions for the computer to execute, similar to a cooking recipe. The essence of imperative programming is to provide statements that tell how to do something. This style of programming is well suited for object oriented programming.

Declarative


A declarative programming language allows you to express what you want without specifying how to get it. An example of declarative programming is SQL (Structured Query Language). In SQL, you don’t tell the query analyzer how to go about fetching the data, you simply state what data you want to retrieve and it takes care of the rest. The declarative style is both simpler to understand and supports greater code reuse. Applications written in this style tend to have greater scalability and performance.


Writing functional

Think in a declarative way; do not write how it should happen, but what should happen.

There are two main features of the functional paradigm that are the exact opposite of imperative programming: functional programming avoids side effects and mutable data. Functional programming does not deal with objects. As the name implies the main focus is on functions and manipulating (transforming) data. In order to master Elixir, developers need to begin thinking about their applications as transformations of inputs to outputs.

For example, a web request comes in, some series of transformations are performed through pipelines, and finally a response is sent out. This style of programming with "pipelines", or small transformations of data, is the essence of Phoenix, Elixir's web framework. In fact, Phoenix is written in Elixir and constitutes an exemplary Elixir application.

Expressions

Everything in Elixir is an expression. Therefore, there will always be a return value without the need for an explicit "return" keyword.

Learning Elixir

"... with expressions, the concept of program flow and execution becomes more evident because we can compose parts of our programs in a way that is more readable and natural." - Kenny Ballou


Functional programming in general promotes using small well defined functions. Elixir programs should consist of aptly named contexts that mindfully namespace functionality and utilize pipelines composed of concise single-purposed functions to transform data. We want our programs to be extensible, scalable, and loosely coupled.

results matching ""

    No results matching ""