# Functions as Abstractions

Let's motivate functions by look at structural recursion over the natural numbers, and trying to capture in code the pattern we've used many times.

We have written a lot of structural recursions over the natural numbers. We started with code like

```
def stackedBoxes(count: Int): Image =
count match {
case 0 => Image.empty
case n => Image.square(20).beside(stackedBoxes(n-1))
}
```

and more recently have been writing code like

```
def polygonPoints(sides: Int, radius: Double): Image = {
val turn = (1.0 / sides).turns
def loop(count: Int): Image =
count match {
case 0 => Image.empty
case n =>
Image
.circle(5)
.at(Point(radius, turn * n))
.on(loop(n - 1))
}
loop(sides)
}
```

The details are different, but the underlying structure of the two examples is the same. In fact that's one of the points we're emphasizing: that code has underlying patterns that apply in many different situations.

When we see this repetition we might wonder if we can somehow capture it in code, so we don't have to write it out again and again. We're going to do this in this section, and in doing so we'll introduce functions.

Let's start by putting the two structural recursions next to each other, and in the case of `polygonPoints`

removing the surrounding code.

```
def stackedBoxes(count: Int): Image =
count match {
case 0 => Image.empty
case n => aBox.beside(stackedBoxes(n-1))
}
def loop(count: Int): Image =
count match {
case 0 => Image.empty
case n =>
Image
.circle(5)
.at(Point(radius, turn * n))
.on(loop(n - 1))
}
```

Keeping the common parts of these methods, and replacing those that vary with `???`

, leaves us with something like

```
def aMethod(count: Int): Image =
count match {
case 0 => Image.empty
case n => ??? aMethod(count - 1)
}
```

This is the code skeleton for structural recursion over the natural numbers.

Now our challenge is to turn this into something we can actually use in Scala. Let's look at the recursive case in the code skeleton

`case n => ??? aMethod(count - 1)`

This is the only part that has a `???`

. In the actual methods we have

`case n => aBox.beside(stackedBoxes(n-1))`

and

```
case n =>
Image
.circle(5)
.at(Point(radius, turn * n))
.on(loop(n - 1))
```

respectively.

To capture this in code we need to allow:

- varying how we build the result of the recursion (in one case it's
`beside`

, while we use`on`

in the other); and - the
`Image`

at the current step to depend on`n`

(as in the case taken from`polygonPoints`

, where we use the value`n`

to determine the location of the circle.)

In other words, the value we build is parameterized by the result of the recursion and the value `n`

. We could express this with a method

`def build(n: Int, recursive: Image): Image = ???`

and then, with two different implementations of `build`

, we could write both original methods in terms of

```
def aMethod(count: Int, build: ???): Image =
count match {
case 0 => Image.empty
case n => build(n, aMethod(count - 1, build))
}
```

However this won't work; we cannot pass a method as a parameter to a method. The solution, of course, is to use a function.

A function is basically a method, but we can use a function as a first-class value:

- we can pass it as an argument or parameter to a method or function;
- we can return it from a method or function; and
- we can give it a name using
`val`

.

Here's how we can solve the problem above using functions. First I'm going to define the method we've been calling `aMethod`

above. I'm going to call it `fold`

, which is the usual name for this kind of method. (This isn't an entirely correct implementation for fold, but we don't have all the tools to do it properly right now. This is something we'll come back to in a later chapter.)

```
def fold(count: Int, build: (Int, Image) => Image): Image =
count match {
case 0 => Image.empty
case n => build(n, fold(count - 1, build))
}
```

This method definition says that the parameter `build`

is a function from two arguments (an `Int`

and an `Image`

) to an `Image`

. To call `fold`

we need to create a function, so let's see an example of that.

```
val aBox = Image.square(20).fillColor(Color.royalBlue).strokeColor(Color.crimson)
val stack = (count: Int, image: Image) => aBox.beside(image)
```

We can now call `fold`

with `stack`

.

`fold(5, stack)`

This produes the output below.

Now that we've seen an example of functions, let's go into the details of defining and using them.

### Function Literals

We've just seen an example of a function literal, which was

`(count: Int, image: Image) => aBox.above(image)`

The general syntax is an extension of this.

#### Function Literal Syntax

The syntax for declaring a function literal is

`(parameter: type, ...) => expression`

where

- the optional
`parameter`

s are the names given to the function parameters; - the
`type`

s are the types of the function parameters; and - the
`expression`

determines the result of the function.

The parentheses around the parameters are optional if the function has just a single parameter.

### Function Types

To pass functions to methods we need to know how to write down their types (because when we declare a parameter we have to declare its type).

We write a function type like `(A, B) => C`

where `A`

and `B`

are the types of the parameters and `C`

is the result type.
The same pattern generalises from functions of no arguments to an arbitrary number of arguments.

Here's an example. We create a method that accepts a function, and that function is from `Int`

to `Int`

. We write this type as `Int => Int`

or `(Int) => Int`

.

```
def squareF(x: Int, f: Int => Int): Int =
f(x) * f(x)
```

We can define a function `add42`

, and pass it to this method

`val add42 = (x: Int) => x + 42`

```
squareF(0, add42)
// res3: Int = 1764
```

We could also pass a function literal

```
squareF(0, x => x + 42)
// res4: Int = 1764
```

Note that we didn't have to put the parameter type on the function literal in this case because Scala has enough information to infer the type.

#### Function Type Declaration Syntax

To declare a function type, write

`(A, B, ...) => C`

where

`A, B, ...`

are the types of the input parameters; and`C`

is the type of the result.

If a function only has one parameter the parentheses may be dropped:

`A => B`

### Functions as Objects

All first class values are objects in Scala, including functions. This means functions can have methods, including some useful means for composition.

```
val addTen = (a: Int) => a + 10
val double = (a: Int) => a * 2
val combined = addTen.andThen(double) // this composes the two functions
```

```
combined(5)
// res5: Int = 30
```

Calling a function is actually calling the method called `apply`

on the function. Scala allows a shortcut for any object that has a method called `apply`

, where can drop the method name `apply`

and write the call like a function call. This means the following are equivalent.

`val halve = (a: Int) => a / 2`

```
halve(4)
// res6: Int = 2
halve.apply(4)
// res7: Int = 2
```

### Converting Methods to Functions

Methods are very similar to functions, so Scala provides a way to convert functions to methods. If we follow a method name with a `_`

it will be converted to a function.

```
def times42(x: Int): Int =
x * 42
```

`val times42Function = times42 _`

```
times42Function(2)
// res8: Int = 84
```

We can also write a method call but replace all parameters with `_`

and Scala will convert the method to a function.

`val times42Function2 = times42(_)`

```
times42Function2(2)
// res9: Int = 84
```

#### Exercises

#### Exercise: Function Literals

Let's get some practice writing function literals. Write a function literal that:

- squares it's
`Int`

input; - has a
`Color`

parameter and spins the hue of that`Color`

by 15 degrees; and - takes an
`Image`

input and creates four copies in a row, where each copy is rotated by 90 degrees relative to the previous image (use the`rotate`

method on`Image`

to achieve this.)

The first function is

```
(x: Int) => x * x
// res10: Function1[Int, Int] = repl.MdocSession$MdocApp0$$Lambda$14832/0x0000000103d18840@14f021d4
```

The second is

```
(c: Color) => c.spin(15.degrees)
// res11: Function1[Color, HSLA] = repl.MdocSession$MdocApp0$$Lambda$14833/0x0000000103d19040@6e16e704
```

The third is

```
(image: Image) =>
image.beside(image.rotate(90.degrees))
.beside(image.rotate(180.degrees))
.beside(image.rotate(270.degrees))
.beside(image.rotate(360.degrees))
// res12: Function1[Image, Image] = repl.MdocSession$MdocApp0$$Lambda$14834/0x0000000103d1a040@131049dd
```

#### Exercise: Function Types

Here's an interesting function we'll do more with in later sections. We don't need to understand what it does right now, though you might want to experiment with it.

```
val roseFn = (angle: Angle) =>
Point.cartesian((angle * 7).cos * angle.cos, (angle * 7).cos * angle.sin)
```

What is the type of the function `roseFn`

defined above? What does this type tell us?

The type is `Angle => Point`

. This means `roseFn`

is a function that takes a single argument of type `Angle`

and returns a value of type `Point`

. In other words, `roseFn`

transforms an `Angle`

to a `Point`

.