# Functions

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 an example where we give the name `add42`

to a function that adds 42 to its input.

```
val add42 = (x: Int) => x + 42
// add42: Function1[Int, Int] = repl.MdocSession$MdocApp$$Lambda$12253/0x00000001034bc840@3a521756
```

We can call it just like we'd call a method.

```
add42(0)
// res0: Int = 42
```

This is an example of a function literal. Let's learn about them now.

### Function Literals

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

```
(x: Int) => x + 42
// res1: Function1[Int, Int] = repl.MdocSession$MdocApp$$Lambda$12254/0x000000010348a840@599d1b41
```

The general syntax is an extension of this.

<div class="callout callout-info">

#### 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. </div>

### 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 pass `add42`

to this method

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

We could also pass a function literal

```
squareF(0, x => x + 42)
// res3: 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.

<div class="callout callout-info">

#### 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`

</div>

### 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
// addTen: Function1[Int, Int] = repl.MdocSession$MdocApp$$Lambda$12256/0x0000000103362840@3db60bff
val double = (a: Int) => a * 2
// double: Function1[Int, Int] = repl.MdocSession$MdocApp$$Lambda$12257/0x0000000103263040@5ac01b73
val combined = addTen.andThen(double) // this composes the two functions
// combined: Function1[Int, Int] = scala.Function1$$Lambda$12187/0x00000001035ab840@70825fda // this composes the two functions
combined(5)
// res4: 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: Function1[Int, Int] = repl.MdocSession$MdocApp$$Lambda$12258/0x00000001027d1840@41f41598
halve(4)
// res5: Int = 2
halve.apply(4)
// res6: 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: Function1[Int, Int] = repl.MdocSession$MdocApp$$Lambda$12259/0x00000001027cf040@4c9017aa
```

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: Function1[Int, Int] = repl.MdocSession$MdocApp$$Lambda$12260/0x00000001027cc840@16d186c8
```

#### Exercises {-}

##### 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.)

<div class="solution"> The first function is

```
(x: Int) => x * x
// res7: Function1[Int, Int] = repl.MdocSession$MdocApp$$Lambda$12261/0x00000001027c3840@744f7747
```

The second is

```
(c: Color) => c.spin(15.degrees)
// res8: Function1[Color, HSLA] = repl.MdocSession$MdocApp$$Lambda$12262/0x000000010217f840@1576e483
```

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))
// res9: Function1[Image, Image] = repl.MdocSession$MdocApp$$Lambda$12263/0x00000001035cd040@59979cc0
```

</div>

##### 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 mean?

<div class="solution">
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`

.
</div>