A Small Introduction to Functional Programming
Tags: haskell, erlang, functional
Published: 2023-01-03 20:48:02

Functional Programming is an old paradigm that’s gained popularity in recent years due to its code conciseness, modularity, and lack of side effects.

Based on [Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus), developed by Alonzo Church in the 1930s, functional programming has been implemented in mainstream programming languages like [JavaScript](https://www.javascript.com/), [Python](https://www.python.org/) and [Java](https://www.java.com/en/). Programming languages like [Erlang](https://www.erlang.org/), [Haskell](https://www.haskell.org/) or [Scala](https://www.scala-lang.org/) are better suited for functional programming as they are designed to be functional first.

Many developers consider [Lisp](https://en.wikipedia.org/wiki/Lisp_(programming_language)) the first functional programming language. For newer incarnations, we can try [Common Lisp](https://lisp-lang.org/) or [Racket](https://racket-lang.org/).

# What makes functional programming so unique?

**Pure functions** → The same input always produces the same output, and there are no side effects (no printing into the screen, mutating your input or changing the filesystem).

**Function are First Class citizens** → Function are treated as data. We can use them as variables, as input for other functions or as return values. Functions are everywhere.

**Shorter code** → Programs written in functional programming languages tend to be shorter than its counterparts like object oriented or imperative programming.

**No loops** → There’s no while, for, do while or anything of the sort as recursion is all you need.

# What do we need?

In this post, we’re going to explore some key fundamentals of functional programming using examples in two different functional languages and you’re invited to install them both, or just install what you want or need.

**Haskell (1990 / Purely Functional)** → If we’re on a Mac, the best way is to use [homebrew](https://brew.sh/) and type on the terminal window:

```bash
$ brew install ghc cabal-install
```

Where **ghc** is the **Glasgow Haskell Compiler** and **Cabal** is Haskell’s package manager.

For other systems, you can refer to the [download](https://www.haskell.org/downloads/) page.

**Erlang (1986 / Concurrent and Functional)** → Again, if on a Mac, type:

```bash
$ brew install erlang
```

Or you can refer to the [download](https://www.erlang.org/downloads) page.

# Immutable variables

In functional programming, once a variable is assigned it can never change. You can think of that as using constants all the time.

## Erlang

In Erlang variables begin with an Uppercase letter and once assigned they cannot be changed.


![Erlang Variables](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iza8lo3cypx3q5psnys1.png)

## Haskell

In Haskell variables don’t follow any structure. Create a file called **variables.hs** and type the following:

```haskell
a = 1
a = 5
```

Then open a terminal window on the same folder as your file and run **ghci**, then **:l variables** to load your program.


![Haskell Variables](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j20mrz91m5wcd47mmx43.png)

# Pattern Matching

In short terms, pattern matching allows us to define how the same function will react to different parameters. This means that calling the function **myFunction** with no parameters will be different from calling **myFunction** with two parameters and different from calling it with five parameters and even different when calling it with different parameter values.

Let’s create an Erlang example called **greetings.erl**:

```erlang
-module(greetings).
-export([greet/2]).
greet(male, Name) ->
    io:format("Good morning Mr. ~s~n", [Name]);
greet(female, Name) ->
    io:format("Good morning Mrs. ~s~n", [Name]);
greet(_, Name) ->
    io:format("Good morning ???. ~s~n", [Name]).
```

When we run it, we can see that we can call the same function but using different parameters and it will always run as expected.


![Erlang Greetings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/us860gwik41wfe7rbuq2.png)

# Anonymous functions

Anonymous functions are functions that do not have a name. We can call them just once. We use them to define functions that are not meant to be called multiple times.

Let’s see an example calling a function to manipulate a list. We’re going to write a file called **lambdas.hs**:

```haskell
func :: Integer -> Integer
func num = num * 2 + 10
show_nums :: [Integer] -> [Integer]
show_nums lst = map func lst
```

We need to call the Haskell compiler to read our file:

```bash
$ ghci 
$ :l lambdas.hs
```

And then call it like this:

```bash
$ show_nums [1,2,3,4,5]
```


![Lambdas](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bu6a46yr2oaykm9kiufg.png)

While this is simple, we don’t really need the **func** function, so let’s change the source code like this:

```haskell
show_lambdas :: [Integer] -> [Integer]
show_lambdas lst = map (\xs -> xs * 2 + 10) lst
```

And it will yield the same exact result, but with half the code lines:


![Lambdas again](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nexaqgu6mersxj5c8e5y.png)

# Closures

A closure is a function inside a function that gets access to its parent function variables. Sounds strange, huh? Let’s see an Erlang example:

We’re going to write this example on a file called **closures.erl**:

```erlang
-module(closures).
-export([start/1]).
start(Name) ->
  GreetPerson = fun() ->
    io:format("Hello and welcome ~s.~n", [Name]),
    fun() -> io:format("Goodbye ~s. Nice to meet you.~n", [Name]) end
  end,
  Greet = GreetPerson(),
  Greet().
```

To run this we need to compile the file first by typing on the terminal:

```bash
$ erlc closures.erl
```

A **closures.beam** file gets generated, which is a file that will be interpreted by the Erlang VM.

After compilation, we need to open the **Erlang VM** and run it.

```bash
$ erl

$ closures:start(“Blag”).
```

This will run and execute our code:


![Closures](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3nk6o3kvtodfdwllz47w.png)

Here we can see that by calling **Greet = GreetPerson()**, we’re assigning the function **GreetPerson()** to the variable **Greet**. When we call **Greet()**, we’re greeting the person, but we’re also running an anonymous function that will say goodbye to the user. Notice that we’re not calling this anonymous function directly.

# List Comprehensions

List comprehensions are a way to build or modify lists, and it is worth mentioning that lists are the most used type in functional programming.

Using list comprehensions, we could rewrite the lambdas example. This time, let’s use Erlang and create a file called **list_comprehensions.erl** with the following code:

```erlang
-module(list_comprehensions).
-export([start/1]).
start(List) -> 
  [X * 2 + 10 || X <- List].
```

When we run this, it will return the same result:


![List comprehensions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rmwh8gbp9splzm4f85nx.png)

# Recursion

When using Recursion, a function calls itself multiple times, and this is not a foreign topic on non-functional programming languages, but the way it’s implemented and used is for sure different.

To make more sense of this, let’s see how a factorial source will look like in [Ruby](https://www.ruby-lang.org/en/):

```ruby
def fact(n)
  if n == 0
    1
  else
    n * fact(n-1)
  end
end
puts fact(5)
```

We can write the same on **Haskell**, like this:

```haskell
factorial :: Int -> Int
factorial 0 = 1
factorial n = n * factorial (n - 1)
```

The code is shorter and simpler:


![Factorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dp11q087hf5jzd5d6i67.png)

And that’s it for a small introduction to functional programming.


![Functional Programming](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wjno1njbsv0xxl1raupc.png)

Like what you read but looking for some Nylas content, make sure to check our great selection of [blog posts](https://www.nylas.com/blog/).

Don’t miss the action, watch our LiveStream Coding with Nylas:

{% embed https://youtu.be/NIB6eg_Zkew %}