Let us start with a set of entities, for example, the cars parked in a given block of a street. One can identify each car by its license plate, and then build a table with two columns: the first one with the license plate, and the second one with the corresponding the color of each car:

Lic. Plate | Color |
---|---|

ABC 124 | black |

DEF 350 | red |

QRZ 441 | black |

JPG 255 | white |

That’s a function that we can call `carColor`

, that associates each car of the block with its color. The table is a representation of that function. A function from a set of entities A to a set of entities B is then a relation that associates elements between the sets A and B, with the property that each and every element of A has a one and only one corresponding element of B.

There are two things to note. First, a function is defined *from* one set *to* another set, in our example, from the set of license plates to the set of colors. To get the color of a particular car, you go to the table representation of the function, look up the plate in the column of license plates, and get the color from the second column. With this in mind, one can identify the *from* set as the *input* of the function, while the *to* set is the *output*.

Second, all elements of the input must relate to some element in the output set. In our example, every car in the block has a color assigned in the table. This means that there cannot be empty cells in the second column of our table.

❓ Can you come up with more examples of functions in the real world?

In math, functions are ubiquitous. Let us assume that $x$ is a real number, and define the function

\[f(x) = x + 1,\]that is, the function that returns the value $x$ plus one. The input set (which is called the *domain* of the function in math) is the set of all real values, $\mathbb{R}$, while the output set (the *codomain* in math) is also $\mathbb{R}$, because adding one to any real number is also another real number. Using the *arrow* notation, the complete definition of the function would be

that can be read as following: $f$ is a function from $\mathbb{R}$ to $\mathbb{R}$ such that $f$ of $x$ is $x + 1$”.

🔔 A slight detour around the codomain. The codomain is the set of entities where the function can possibly map input values into. For example, in the case of the color of the cars, the codomain is simply the set of all the possible colors. In many cases that information is too general, and it is convenient to define the

rangeof the function, which is the set of actual values of outputs the function maps inputs into. The range in the cars example is the set {black, red, white}.

Let us take the example of a vending machine. In a vending machine, products are arranged in shelves, where each shelf is named by a letter. In each shelf, the products are aligned and identified by a number. Then, in A1 you have a bag of chips, in A2 a chocolate, in B1 a soda, and so on. The machine also has a keyboard with letters and numbers for you to choose the product. To buy something, you need to give the machine some money (coins, bills, credit card, etc), select the product by clicking the letter and the number on the keyboard. The machine returns the product and some cashback, if any.
The inputs of our `vendingMachine`

function are the money, the letter and the number you selected, and the outputs are the product and
the cashback (if any).

An example from math could be a translation function, where given a point with coordinates (x) and $y$ in the plane, it returns a point with coordinates $x+1$ and $y+1$:

\[g: \mathbb{R} \times \mathbb{R} \rightarrow \mathbb{R} \times \mathbb{R} \; ; \; (x,y) \mapsto (x + 1, y+1)\]or more succintly

\[g(x,y) = (x+1,y+1)\]When we feed a function of several input elements, we can obtain the proper output(s). But having many inputs opens a new possibility: what happens when one decides not to complete all the inputs? Let us find out. Let us assume that we entered a bill into the vending machine. It is clear that we will not get any product, because the machine still needs two more inputs: the letter of the shelf and the product number that we want. *After* we complete these two inputs, we will get our treat (and cashback, if any). So, entering money only in the vending machine leads to a state where two inputs are needed and two outputs will be returned. But, this is *another function*!!!. Let us call it `vendingMachineAfterInsertBill`

that receives the letter of the shelf and the product number that we want and returns the product (and cashback, if any).

Going back to the math example, let us feed the function with just the $x = 3$ value,

\[g(3,y) = (4,y+1)\]Again, the result of feeding the function with one value is another function:

\[h: \mathbb{R} \rightarrow \mathbb{R} \times \mathbb{R} \; ; \; y \mapsto (4, y+1)\]or

\[h(y) = (4,y+1)\]This property of functions is called *partial application*. Whenever you do not complete all the inputs of a function, you get another function.

Finally, we look here how to work with several functions at once. Let us assume that we have a function `getFirstName`

that given the full name of a person, it returns the first name (it does not matter at this point the specifics of the implementation, not even the language). For example, when applied to ‘David Gilmour’, it returns ‘David’, or when applied to ‘Annie Lennox’, it returns, of course ‘Annie’.
We also have a function `getInitial`

that for a given name, it returns the initial. In the previous cases, ‘D’ for ‘David’ and ‘A’ for ‘Annie’.

Now we want to build a function that gives us the initial of the first name, given the full name. For ‘Paul McCartney’. We feed ‘Paul McCartney’ as input to the function `getFirstName`

, which gives us the output ‘Paul’. Now, ‘Paul’ is the input of the function `getInitial`

and returns ‘P’ as the final output.
This plumbing where the output of one function is the input of another is called *composition*. Note that it is absolutely necessary that the output of the first called function (`getFirstName`

) and the input of the second one (`getInitial`

) are the same kind of entity, in our case, both are first names.
You can see this pictures for a graphical explanation.

Let us now look at a math example. We defined before the function $f(x)$ that adds one to $x$, for example

\[f(0) = 0 + 1 = 1\]What if we apply the $f$ function again? It means to compute

\[f(f(0)) = f(0) + 1 = 0 + 1 + 1 = 2\]In general,

\[f(f(x)) = f(x) + 1 = x + 1 + 1 = x + 2\]If we look carefully to the last expression, it looks like composing the function is like passing the function as the input itself ($f(f(x))$). This means that if we are going to have a programming language that implements function composition, in some way functions should be able to be passed as input to another functions.

❗️ The fact that we use the same function to compose with itself is not relevant to this discussion, one can compose as many different functions as one wants, provided that inputs and outputs are compatible in each composition step.

🔔 However, composing that particular function with itself is interesting. Imaging having only the zero and this function. You can create all the natural numbers {1, 2, …} just by composing this function with itself again and again. For example, $4 = f(f(f(f(0))))$, and so on. Therefore, given the number 0, $f(x) = x + 1$ and function composition, one can get all the natural numbers. Looks like there is something going on here. More on this, hopefully, in a future episode.

The F# language implements functions in such a way that they satisfy the properties mentioned above. To define a function, the language also uses the keyword `let`

:

```
let next x =
x + 1
```

We defined the function named `next`

that receives an argument `x`

. Notice that there are no other symbols or parentheses in the function definition. The body of the function should be indented, and there is no `return`

keyword at the end. The function simply returns the last expression found in its body. Clean, isn’t it?
Using the function is easy as well:

```
let one = next 0
let two = next (next 0)
printfn "one: %A" one
printfn "two: %A" two
```

```
one: 1
two: 2
```

Notice that there is no need to use parentheses around the argument when using a function. However, you need to use them when passing a more complex expression as the argument to the function, such as in the case of `two`

.

There is another way to write the computation of `two`

, by using the *pipe operator* `|>`

:

```
let anotherTwo =
0
|> next
|> next
printfn "anotherTwo: %A" anotherTwo
```

```
anotherTwo: 2
```

This operator takes care of the plumbing when calling functions one after another. In the example above, the first `|>`

receives `0`

as the input, passes it to the next function, the second `|>`

receives the output of the first `next`

function and feeds it as input to the second `next`

.

Another example. Let us assume that we have the functions `getInitial`

and `getFirstName`

defined as:

```
let getInitial name =
.... //Implementation not important right now
```

and

```
let getFirstName fullName =
.... //Implementation not important right now
```

and we defined the value

```
let paul = "Paul McCartney"
```

Then,

```
paul
|> getFirstName
|> getInitial
```

Here the string value `paul`

is fed into the `getFirstName`

function as the input by the first pipe `|>`

, and returns ‘Paul’ as output. Then, the string ‘Paul’ is passed as the input of the function `getInitial`

that gives us the ‘P’.

Composition is so important in functional languages, that it has its own symbol in F#, `>>`

:

```
let add2 = next >> next
let two' = add2 0
printfn "%A" two'
```

```
2
```

Yes, you can use the `'`

symbol in any identifier! (provided it is not the first character). Note also that we defined a *function* `add2`

by using the composition operator (no argument needed). This is equivalent to:

```
let add2' x =
x
|> next
|> next
```

Remember that there is no return at the end of the function, just the last expression of the function is the return value.

Back to the names example, to clarify the order in which functions are composed.

```
let getInitialFromFirstName fullName =
fullName
|> getFirstName
|> getInitial
```

and

```
let getInitialFromFirstName' =
getFirstName >> getInitial
```

are equivalent.

❓ Think about routines, procedures or functions that maybe you have written in your language of preference. Do they behave as F# functions? What are the main differences you see?

🏋🏽 We have a function

`mult2`

that given a number`x`

doubles that number. Without coding, can you determine what the next composite functions return when applied to 3? :

```
let f = mult2 >> next
let g = next >> mult2
```

Code the function `mult2`

and see the result by yourself.

Some final remarks for now on functions. First, note that the language use the same keyword `let`

to bind simple values and functions to a name or identifier. This emphasizes the fact that in F# functions are ‘just’ values, and can be treated in the same way as, say, a simpler binding of an expression to an identifier.
Second, the properties of functions that were discussed above match perfectly inmutability. In fact, functions receive immutable inputs and return an immutable value.