# 3.10

## Function

The good old space race is back on. Wouldn’t it be great if we could help out some of these incredibly ambitious companies by letting them reuse our code to find out whether or not their spaceship can leave the Earth too? We can do that by creating a function that encapsulates our logic. Before we do that, let’s understand what a function is in mathematics first.

You may be wondering why I keep taking you back to the wonderful world of mathematics every time I try to explain a concept in Elm. That’s because Elm is a functional programming language which gives it a strong mathematical foundation. Elm implements concepts from mathematics without distorting them. So by understanding how they work in mathematics first, it’s easier to understand them later in Elm. As a bonus, you know where these concepts originally came from. This doesn’t mean you need to have a strong background in mathematics to learn Elm. Everything you need to learn Elm is covered in this book including the mathematical concepts.

A function, in mathematics, is a relationship from a set of inputs to a set of possible outputs where each input is mapped to exactly one output. Functions in Elm also work the same way.

Let’s write a function in Elm called `escapeEarth` that takes a value from an input set of velocities and maps it to a value from an output set of instructions.

We can now call this function with different velocities to find out whether or not a spaceship can leave the Earth.

Like `if` expression, we can assign the value returned by a function to a constant.

### Function Syntax

Functions are so critical to Elm applications that Elm provides an incredibly straightforward syntax for creating them. No ceremony is required, such as using a special keyword or curly braces which is common in many languages.

### Function Application

Once we create a function, we need to apply it to a value to get a desired output. In mathematics, function application is the act of applying a function to a value from the input set to obtain a corresponding value from the output set. You have already seen an example of a function application above: `escapeEarth 11`. When a function is applied, its name should be separated from its argument with whitespace. If a function takes multiple arguments, they too should be separated from each other with whitespace.

Parameter vs Argument
The terms parameter and argument are often used interchangeably although they are not the same. There is no harm in doing so, but just to clear things up, an argument is used to supply a value when applying the function (e.g. `escapeEarth 11`) whereas a parameter is used to hold onto that value in function definition (e.g. `escapeEarth velocity`).

Earlier we learned that all Elm applications are built by stitching together expressions. How do functions fit into this organizational structure? Functions are values too like numbers and strings. Since all values are expressions, that makes functions expressions as well. Because of this, functions can be returned as a result of a computation. They can be passed around like any other value. For example, we can give them to another function as an argument. Functions that take other functions as arguments or return a function are called Higher Order Functions. We will see many examples of higher order functions soon.

### Functions with Multiple Parameters

The `escapeEarth` function above takes only one argument: `velocity`. But, we can give it as many arguments as we want. Let’s add one more parameter to its definition so that it can tell us whether or not our horizontal speed is fast enough to stay in an orbit.

The next code we will write is a bit difficult to type in the repl without making any mistakes. So we will write it in a file instead. Create a new directory called `elm-examples` in the root directory (`beginning-elm`) of the Elm project we created in the last chapter. Inside that directory create a file named `Playground.elm`. We will use this file to experiment with various concepts in Elm. Here is how the directory structure should look like so far.

Filename
Elm style conventions dictate that filenames are also written in Camel Case. Unlike constants, the first letter in a filename should be written in uppercase though. The first letter of each subsequent concatenated word should be capitalized. Elm doesn’t throw an error if we don’t follow this convention, but there is no reason not to follow it.

Put the following code in `Playground.elm`.

The first two lines define a new module called `Playground` and import the `Html` package. Don’t worry about `module` and `import` yet; we’ll cover them later. Next is our function `escapeEarth`. We give it one more parameter called `speed`. If the `velocity` is not greater than `11.186`, it will use the `else if` branch to compare if the `speed` is equal to `7.67`. If yes, it returns “Stay in orbit”. Otherwise, it falls to the `else` branch.

The last function is `main`. The execution of all Elm applications start with this function. It’s a regular function like any other. It just happens to be the entry-point for an application. We apply a function called `Html.text` to the result produced by yet another function application: `escapeEarth 11.2 7.2`. `Html.text` takes a string and displays it on a browser. It’s important to surround `escapeEarth` and its arguments with parentheses. Otherwise, Elm will think we are passing three arguments to `Html.text` which takes only one argument. This is because Elm uses whitespace to separate a function name from its arguments. We can chain as many function applications as we want.

Go to the `beginning-elm` directory in your terminal and run `elm-reactor`. After that open this URL on a browser: `http://localhost:8000/`. You should see `elm-examples` as one of the directories listed in File Navigation section. Click on it. You should see the `Playground.elm` file. If you click that file too, `elm-reactor` will compile the code in it and display the result. You should see the string “Godspeed” on a browser.

### Partial Function Application

When we applied the `escapeEarth` function above, we pulled the value for speed out of thin air. What if it’s actually computed by another function? Add the following function definitions right above `main`.

`speed` takes two parameters: distance covered by a spaceship and travel time. Time in turn is computed by another function called `time`. Here’s how the main function looks when we delegate the calculation of speed to our newly created functions:

Yikes! Chaining multiple function applications looks hideous and hard to read. But what if we write it this way instead:

Ah, much better! To compile the new code, refresh the page at `http://localhost:8000/elm-examples/Playground.elm`. You should see the string “Stay in orbit”.

The nicely formatted code above is possible because Elm allows partial application of functions. Let’s play with some examples in repl to understand what partial functions are. Create a function called multiply with two parameters in the repl.

When we apply it to two arguments, we get the expected result.

But, what if we only give it the first argument?

Hmm… It returns a function instead of giving us an error. Let’s capture that function in a constant.

Let’s see what happens if we apply this intermediate function to the second (and final) argument.

`multiplyByThree` is a partial function. When Elm sees that we haven’t given enough arguments to a function, instead of complaining it applies the function to given arguments and returns a new function that can be applied to the remaining arguments at a later point in time. This has many practical benefits. You will see plenty of examples of partial function application throughout the book.

### Forward Function Application

Let’s get back to that fancy `|>` operator that made our code look so pretty. It’s called the forward function application operator. Since that name is too long, the Elm community refers to it as the pipe operator. It is very useful for avoiding parentheses. It pipes the result from previous expression to the next one.

The pipe operator takes the result from the previous expression and passes it as the last argument to the next function application. For example, the first expression in the chain above (`time 2 3`) generates number `1` as the result which gets passed to the `speed` function as the last argument.

### Backward Function Application

There is another operator that works similarly to `|>`, but in backward order. It’s called the backward function application operator and is represented by this symbol: `<|`. Let’s deviate from our spaceship saga for a bit and create some trivial functions to try out the `<|` operator. Add the following function definitions right above `main`.

`add`, `multiply`, and `divide` are functions that do exactly what their names suggest. Let’s create an expression that uses these functions. Modify the `main` function to this:

Ugh. Even more parentheses. Refresh the page at `http://localhost:8000/elm-examples/Playground.elm` and you should see `35`. The `add` function returns a number, but `Html.text` expects a string. That’s why we need to use the `toString` function to convert a number into a string. It turns any kind of value into a string.

Let’s use our knowledge of the `|>` operator to turn the expression in `main` into a beautiful chain.

We can also write it using the `<|` operator.

Working backwards to forwards can be confusing. Just because you can do it in Elm, doesn’t mean you should. If you feel like you’re in Bizarro World, where down is up and up is down, go ahead and stick with the forward application (`|>`). Elm provides other higher-order helper operators like these. You can learn more about them here.

### Operators are Functions Too

In Elm, all computations happen through the use of functions. As it so happens, all operators in Elm are functions too. They differ from normal functions in three ways:

#### Naming

Operators cannot have letters or numbers in their names whereas the normal functions can. `+++` is an illegal operator in Elm, but we can legitimize it by defining it ourselves. Add the following definition right above `main` in `Playground.elm`

We have given `+++` the same behavior as the `++` operator which is already defined in Elm. `++` is used to concatenate two strings. Notice how the operator is surrounded by parentheses in its definition. We have to do that when we define custom operators using the function syntax. By default, custom operators have the highest precedence (`9`) and are left-associative. Like any other built-in operator, we can apply `+++` to its arguments.

If you refresh the page at `http://localhost:8000/elm-examples/Playground.elm`, you should see “Peanut butter and jelly”. Let’s see what happens if we add a letter to a custom operator’s name.

Elm doesn’t like that.

What about normal functions? Can we include a special character in their name?

Nope. Elm doesn’t like that either. Before moving on, you should remove the invalid operator and function definitions (listed above) from `Playground.elm`.

#### Number of Arguments

Operators accept exactly two arguments whereas there is no limit to how many arguments a normal function can have.

#### Application Style

Operators are applied by writing the first argument, followed by the operator, followed by the second argument. This style of application is called infix-style.

Normal functions are applied by writing the function name, followed by its arguments. This style of application is called prefix-style.

We can also apply operators in prefix-style if we so choose to.

The operators must be surrounded by parentheses. We can’t apply normal functions in infix-style. But, we can create something that resembles infix-style by using `|>`.