---
jupyter:
  jupytext:
    split_at_heading: true
    text_representation:
      extension: .Rmd
      format_name: rmarkdown
      format_version: '1.1'
      jupytext_version: 1.2.4
  kernelspec:
    display_name: Python 3
    language: python
    name: python3
---

# Introduction to functions

This is a very short introduction to functions.

Functions are *recipes* with names [^berkeley-thanks].

[^berkeley-thanks]: Thanks to [the Berkeley
  team](https://www.inferentialthinking.com/chapters/08/Functions_and_Tables)
  for this metaphor.

Let's start with an example where you have seen functions - mathematics.

## cosine

You have used functions in mathematics.  For example, `cosine` is a function in
mathematics.  We often write the `cosine` function as `cos`

We might write something like this, in mathematics:

$$
y = cos(0)
$$

You can read $cos(0)$ as:

> Call the function "cos" with the value 0, and return the result.

Then $y = cos(0)$ means:

> Call the function "cos" with the value 0, and return the result, storing the
> result in "y".

We *pass* a value to the function.  In our case we pass the value $0$.  The
value that we pass is called the *argument*.

The function *returns* a value.  In our case it returns the calculation of the
cosine of $0$.

You may remember that the cosine of 0 is 1.  So, after $y = cos(0)$, we expect
$y$ to equal 1.

Functions in Python work in a similar way.

## Functions in Python

First we load up the `cos` function from a library called `numpy`.

Don't worry about the command to load the function, for now.  We will come back
to that later.  Here is the command you need. Just run it in the notebook.

```{python}
# Get the cos function from the numpy library.
from numpy import cos
```

Now we *call* the `cos` function, *passing* the value 0, and see what we get:

```{python}
cos(0)
```

* `cos` is the *name* of the function;
* `0` is the *value* we *pass* to the function.
* The value we pass to the function goes between the parentheses `(` and `)`
  [^brackets].
* `1.0` is the value that the function *returns*.  It is the *return value* of
  the function.

[^brackets]: Please be very careful to distinguish between different types of
  brackets in Python (and other languages).  The different types of brackets
  are: *parentheses* (round brackets), as in `()`; *square brackets* as in
  `[]`; and *curly brackets* as in `{}`.  These brackets have different
  meanings to Python; if you use the wrong type of brackets, you will either
  get an error, or you will get a result you didn't expect.  Calling functions
  uses parentheses.

The value we pass to the function is also called the function *argument*.

In our case we pass `0` as the *argument* to the `cos` function.

We can also store the return value in a variable, like this:

```{python}
y = cos(0)
```

```{python}
y
```

As you will see, it's a very common pattern in Jupyter notebooks to store the
value, and then show the value, in the same cell, like this:

```{python}
y = cos(0)
y
```

Read this code as:

> Pass the value 0 to the `cos` function.  Put the result into the variable
> `y`. Show the contents of variable `y`.

## Again with the recipe metaphor

A recipe is the *procedure* to go from *ingredients* to a *meal*.

A function is the *procedure* to go from the *arguments* to the *return value*.

The *arguments* are the things that I send to the function.  The *return value*
is the thing that the function sends back.

It is the job of the function to do some work on the arguments, and return the
correct return value.

For example, I might have a recipe with the procedure to go from the
ingredients: two eggs; butter; and cheese \- to the meal \- a cheese omelette.

The function `cos` has the procedure to go from the input argument - a number -
to the return value, which is the calculation of the cosine of the value of the
input argument.

I could call my recipe "two egg cheese omelette", or "recipe number
4".  Whatever I called it, it would be the same recipe.  I might
prefer a name that describes what the recipe makes, to help me
remember.

Likewise, the name `cos` refers to a procedure above.  The folks who wrote the
Numpy library could have give it another name, like `some_function`, but `cos`
is a good name, because it helps us remember what the procedure does.


## Practice with functions

So far we have used the `cos` function from Numpy.  Let's try doing the same
thing with the `sin` function:

```{python}
# Get the sin function from the numpy library.
from numpy import sin
```

```{python}
sin(0)
```

* `sin` - the function name;
* `0` - the value we pass to the function;
* The value goes after the function name, and between parentheses;
* `0.0` - the value that the function returns.

We pass `0` as the *argument* to the `sin` function.


Now your turn.

Try importing the `sqrt` function.  Yes, you guessed it, `sqrt` is the
procedure to go from a number (the argument) to the square root of that number
(the return value).

```{python}
# Get the sqrt function from the numpy library.
# Your code here.
```

Call the `sqrt` function with the value `9`; you should see this returns the value `3.0`.

```{python}
# Your code here.
```

Use Python to show that $3^2$ is indeed 9:

```{python}
# Your code to show the value of 3 squared.
```

We will see more about functions in the section on [call expressions](Calls).
