Menu

- Chapter 1 Distilled
- Introduction
- 1.1 - The Elements Of Programming
- Expressions
- Naming and the Environment
- Evaluating Combinations
- Defining New Functions
- The Substitution Model
- Exercises
- Predicates
- Conditional Expressions
- Example: Newtonâ€™s Method
- Functions as Black-Box Abstractions
- 1.2 - Procedures and the Processes They Generate
- Linear Recursion and Iteration
- Tree Recursion
- Orders of Growth
- Exponentiation
- Example: Testing For Primality
- 1.3 Higher Order Functions
- Project - Blackjack

- Chapter 2 Distilled
- Introduction
- Data Abstraction
- Everything From Nothing
- Abstractions In Clojure
- Clojure's Data Structures
- Data Abstraction, Revisited
- Escher
- Project - Escher
- Symbolic Data
- Representing Sets
- Huffman Encoding Trees
- Zippers

So far we have:

- Data (numbers, strings, keywords, chars)
- Functions (arithmetic)

We can:

```
(+ (* 3 5)
(- (/ 4 3) (* 2 9)))
```

```
(def a 3)
(+ a 2)
```

Now we will learn how to make our own functions, and learn our first model of how to evaluate them.

We can make a function that squares a number:

```
(defn square [x]
(* x x))
```

In general we create functions as follows:

```
(defn <name> [<formal parameters>]
<body>)
```

The `<name>`

is a symbol to be associated with the function defined, in the global environment.

The `<formal parameters>`

are the names used within the body of the function to refer to the corresponding arguments of the function.

The `[ ]`

is actually a Clojure *vector*, we look at data structures in Ch2.

The `<body>`

is an expression that will yield the value of the function application when the formal parameters are replaced by the actual arguments to which the function is applied.

Once we name it, we can of course use it in expressions

```
> (square 21)
441
```

```
> (square (+ 2 5))
49
```

```
> (square (square 3))
81
```

We can have multiple arguments to our functions:

```
(defn spread [x y z]
(- (max x y z) (min x y z)))
```

This function computes the range of 3 numbers, I called this `spread`

rather
than `range`

as `range`

is a builtin function in Clojure.

If we call a function with the wrong number of arguments, we get an error

```
> (spread 10)
clojure.lang.ArityException:
Wrong number of args (1) passed to:
sandbox24425$spread
```

The technical word for number of arguments is *arity* (that's why we get an `Arityexception`

here)

We can specify different arities for the same function

```
(defn spread
([x] x)
([x y] (- (max x y) (min x y)))
([x y z] (- (max x y z) (min x y z))))
```

Or we can do *variadic* (ie a variable number of arguments)

```
(defn spread [& nums]
(- (apply max nums) (apply min nums)))
```

Here the arguments are collected as a sequence called `nums`

.

`apply`

takes a function and a sequence and calls the function with the elements
of the sequence as args, so

```
(apply max [5 1 7 4])
```

is the same as

```
(max 5 1 7 4)
```