# functions 7: More tricks

# Single line functions

There are more tricks you can do with functions in Julia. If the function is short, you can simply define it as shown:

```
y(x) = 2x + 3
```

Output:

```
y (generic function with 1 method)
```

Noe we call `y(7)`

as shown below:

```
y(7)
```

Output:

```
17
```

Doesn’t it look very mathematical? That’s why many math people use Julia and I feel its better for A.I, as A.I is nothing but math.

# Functions acting on a vector

Do you know that a function can operate on a vector? We use the same function `y()`

defined above on a vector, see the code below:

```
y.([1, 2, 3, 4])
```

Output:

```
4-element Array{Int64,1}:
5
7
9
11
```

See how `y()`

just takes single argument `x`

and returns a value, but `y.()`

that is with a dot can take a vector, operate on it element wise one by one, pack it into a vector and return it out. It’s not that functions in a single line can do it, any function can do it as shown below:

```
function y1(x)
2x + 3
end
```

Output:

```
y1 (generic function with 1 method)
```

```
y1.([1, 2, 3, 4])
```

Output:

```
4-element Array{Int64,1}:
5
7
9
11
```

And this function with a `.`

can operate on ranges too:

```
y.(1:10)
```

Output:

```
10-element Array{Int64,1}:
5
7
9
11
13
15
17
19
21
23
```

# Using functions with map

There is a function called `map()`

which takes function as argument and iterateable thing as second argument, say `Array`

, `Tuple`

or `Range`

, then it takes each element in the iterator, apply the function on it, takes the result, packs it into an array and returns it to us.

Take a look at the code below, see how we map `y`

on to a `Array`

```
map(y, [1, 2, 3, 4])
```

Output:

```
4-element Array{Int64,1}:
5
7
9
11
```

# Anonymous function

It is not that a function should always have a name, it could be anonymous too, take a look at the code below, type it and execute it:

```
map(x -> 2x + 3, [1, 2, 3, 4])
```

Output:

```
4-element Array{Int64,1}:
5
7
9
11
```

We have `map()`

, rather than giving a name of a function as the first argument, we give `x -> 2x + 3`

, that is the function has no name, but an argument `x`

followed by arrow `->`

followed by the return value `2x + 3`

, and it works like charm.

# Variable Arguments

Its not that there must be fixed set of arguments that are passed to a function, you can pass variable number of arguments too as shown, type the function below in a Jupter lab cell:

```
function vararg_sum(numbers...)
total = 0
for number in numbers
total += number
end
total
end
```

Output:

```
vararg_sum (generic function with 3 methods)
```

So a function was created, now let’s use it with a single argument:

```
vararg_sum(8)
```

Output:

```
8
```

So it works. Now let’s try many arguments:

```
vararg_sum(8, 2, 3, 4, 5)
```

Output:

```
22
```

It works too! We will soon see how it works.

A variable that gets variable argument is at the end of the function. It has a name `numbers`

in out case, and is followed by a triple dot `...`

as in `function vararg_sum(numbers...)`

. Inside the function the variable named `numbers`

and not `numbers...`

stores all the argument. We will see how it stores soon. Julia gets a hint hat a variable need to store vrible arguments if its followed by triple dot `...`

.

A variable argument variable should always be at the end of the function if we are using other variables as named and positional arguments. The below function find total of `numbers`

and adds it with a base `base`

. As you can see the variable argument is at the end of the function.

```
function vararg_sum_with_base(base = 0, numbers...)
total = base
for number in numbers
total += number
end
total
end
```

Output:

```
vararg_sum_with_base (generic function with 2 methods)
```

and once again it works as shown below:

```
vararg_sum_with_base(5, 1, 2, 3, 4)
```

Output:

```
15
```

In the below example, all we are interested is to see what `numbers`

hold. So let’s print it out:

```
function vararg(base = 0, numbers...)
total = base
println(numbers)
println(typeof(numbers))
end
```

Output:

```
vararg (generic function with 2 methods)
```

We call the function

```
vararg(1, 2, 3, 4, 5)
```

```
(2, 3, 4, 5)
NTuple{4,Int64}
```

As you see `number`

inside the function is nothing but a `Tuple`

packed with all the values we pass as argument.

# Piping / Chaining functions

Julia has this nice idea of chaining functions, the below code is equivalent to `sum(1:10)`

:

```
1:10 |> sum
```

Output:

```
55
```

So in the above code we see that `1:10`

is piped to `sum()`

. The output of this can be piped to `sqrt()`

as shown below:

```
1:10 |> sum |> sqrt
```

Output:

```
7.416198487095663
```

So the above code is equivalent to `sqrt(sum(1:10))`

, but it looks more elegant. The same operation is done by code below using the circle operator, you can type it by typing `\circ`

and pressing `Tab`

in your notebook:

```
(sqrt ∘ sum)(1:10)
```

Output:

```
7.416198487095663
```

Notice how in piping things pass from left to right here `1:10 |> sum |> sqrt`

and right to left here `(sqrt ∘ sum)(1:10)`

.

So these are the useful things about functions I feel we as data scientist must know.

You can get the Jupyter notebook file for this blog here https://gitlab.com/data-science-with-julia/code/-/blob/master/functions.ipynb.