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

#'user/add

(add 1 2 3)

6


### Declaring function¶

(defn add [x y z]
(+ x y z))

#'user/add

(add 1 2 3)

6


### Anonymous function¶

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

#'user/add

(add 1 2 3)

6


(defn add-many [x y z & rest]
(println "adding" x y z "and also" rest))

#'user/add-many

(add-many 1 2 3)

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

#'user/add-numbers

(add-numbers {:x 1
: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¶

(def p (partial add-many 100))

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