# All you need is Lambda

### Lambda Abstraction

To generalize and abstract out a repetitive computation

`double` the input - to double the input is to add it to itself

```(lambda (x) (+ x x))
```
```\x -> x + x
```

or take it two times

```(*2)
```

`square` a value - to square a value is to multiply it by itself

```(lambda (x) (* x x))
```
```\x -> x * x
```

or rise it into a second power

```(^2)
```

### Application of a Procedure

```((lambda (x) (* x x)) 3)
;Value: 9
```

### Let expression - local bindings

`let` is just a closure along with its application. It creates a local binding or a local context and evaluates an expression within it.

```(let ((a 2)) (* a a))
;Value: 4
```

is semantically equivalent (actually, a syntactic sugar) for

```((lambda (a) (* a a)) 2)
;Value: 4
```
```let c = |x| {
x * x
};
```

### Closure property

As long as there is no free variables within an expression (all the bindings are local to this `lambda`) the whole term is called a closure.

It literally means everything is enclosed within, as in a cell's membrane. Closures are cells - basic building blocks.

### Naming

```(define double (lambda (x) (* 2 x)))
```
```double x = x + x
```

same functions, different procedures (implementations of algorithms)

### Equation reasoning

```double x = x * 2
```
```double = (*2)
```

### Constant function

```(define three (lambda () 3))
```

An immutable binding acts as a function (a lookup table)

```(define three 3)
```

### Simple Typing

Typing is literally partitioning of The Universe Of Values into sets according to some properties (or traits).

We might choice to annotate types of our bindings.

```(x: Int) => x + x
```

### Generic functions

```(lambda (x) x)
```
```id x = x
```
```((lambda (x) x) (lambda (x) x))
```