# ✓ Functions¶

In this section, we will have an indepth discussion of functional programming.

## Declaring Functions revisited¶

### Function as value¶

(def add (fn [x y z] (+ x y z)))
6

(+ x y z))
6

### Anonymous function¶

(def add #(+ %1 %2 %3))
6

(defn add-many [x y z & rest]
(println "adding" x y z "and also" rest))
adding 1 2 3 and also nil
nil
(add-many 1 2 3 4 5 6 7)
adding 1 2 3 and also (4 5 6 7)
nil

### Destructuring hash-map parameters¶

(defn add-numbers [{:keys [x y z more]}]
(println "adding" x y z "and also" more))
:y 2
:z 3
:more [4 5 6]})
adding 1 2 3 and also [4 5 6]
nil

## Partial functions¶

### Definition of partial function¶

Suppose we have a function $$f(x, y, z, \dots)$$ with parameters $$x, y, z, \dots$$. A partial function of $$f$$ is a function defined by fixing certain parameters of $$f$$.

$p(y, z, \dots) = f(\mathrm{value}, y, z, \dots)$

### Create partial functions¶

#'user/p
(p 1 2 3 4 5)
adding 100 1 2 and also (3 4 5)
nil

## Apply functions¶

### Function application from a data perspective¶

Consider a function application below.

(add-many 1 2 3 4 5)

It can be seen as two pieces of data:

1. the function expression: in this case add-many

2. a collection of argument expressions: in this case 1, 2, 3, 4, 5

Clojure provides a function apply that can perform the function invocation when provided the function and argument list.

### Apply¶

(apply <function> <arguments>)
(apply <function> <first-arg> <arguments...>)
(apply <function> <first-arg> <second-arg> <arguments...>)
(apply add-many [1, 2, 3, 4, 5])
adding 1 2 3 and also (4 5)
nil
(apply add-many 100 [1 2 3 4 5])
adding 100 1 2 and also (3 4 5)
nil

### Defining partial functions using apply¶

(defn p [y z & more]
(let [arguments (concat [y z] more)]
#'user/p
(p 1 2 3 4 5)
adding 100 1 2 and also (3 4 5)
nil

## Summary¶

### Three ways of function abstraction:¶

1. (fn [...] ...)

2. (defn f [...] ...)

3. #(...)

### Functions can have arbitary parameters¶

1. Destructuring the arguments [ ... & <rest-args> ]

2. Rest of the arguments are in a list.

### Partial functions¶

1. (partial f ...)

2. Define a new function with (apply ...)