## Function the Ultimate

`this`

- The
`this`

parameter contains a reference to the object of invocation. `this`

allows a method to know what object it is concerned with.`this`

allows a single function object to service many objects.`this`

is key to prototypal inheritance.

### 4 ways to call a function

- Function form
`functionObject(arguments)`

- Method from
`thisObject.methodName(arguments)`

`thisObject[methodName](arguments)`

- Constructor form
`new FunctionObject(arguments)`

- Apply form
`functionObject.apply(thisObject, [arguments])`

#### Function form

When a function is called in the function form, `this`

is set to the global object.

#### Method from

When a function is called in the method form, `this`

is set to `thisObject`

, the object containing the function.

This allows methods to have a reference to the object of interest.

#### Constructor form

When a function is called with the `new`

operator, a new object is created and assigned to `this`

.

If there is not an explicit return value, then `this`

will be returned.

Used in the Pseudoclassical style.

#### Apply form

A function’s `apply`

or `call`

method allows for calling the function, explicitly specifying `thisObject`

.

It can also take an array of parameters or a sequence of parameters.

### Closure

1 | var digit_name = (function () { |

### Side Effects

**Programming without side-effects:**

Remove assignment, loops(use recursion instead), freeze all array literals and object literals.

Remove `Date`

and `Math.random`

## Problems

`funky`

1 | function funky (o) { |

## What is x?

`[]`

`swap`

1 | function swap (a, b) { |

## What is x?

`1`

`identity`

#### Write a function that takes an argument returns that argument.

## Solution

1 | function identity (x) { |

#### Write two binary functions `add`

and `mul`

, that take two numbers and return their sum and product.

1 | add(3, 4) // 7 |

## Solution

1 | function add (x, y) { |

#### Write a function that takes an argument and return a function that return that argument

1 | idf = identityf(3) |

## Solution

1 | function identityf(x) { |

#### Write a function that adds from two invocations

1 | addf(3)(4) // 7 |

## Solution

1 | function addf (x) { |

#### Write a function that takes a binary function, and makes it callable with two invocations.

1 | addf = applyf(add) |

## Solution

1 | function applyf (binary) { |

#### Write a function that takes a function and an argument, and returns a function that can supply a second argument.

1 | add3 = curry(add, 3) |

## Solution

1 | function curry (func, first) { |

#### Without writing any new functions, show three ways to create the `inc`

function

1 | inc(5) // 6 |

## Solution

1 | 1. inc = addf(1) |

#### Write `methodize`

, a function that converts a binary function to a method.

1 | Number.prototype.add = methodize(add) |

## Solution

1 | function methodize (func) { |

#### ✔️ Write `demethodize`

, a function that convert a method to a binary function.

1 | demethodize(Number.prototype.add)(5, 6) // 11 |

## Solution

1 | function demethodize (func) { |

#### ✔️ Write a function `twice`

that takes a binary function and returns a unary function that passes its argument to the binary function twice.

1 | var double = twice(add) |

## Solution

1 | function twice (binary) { |

#### ✔️ Write a function `composeu`

that takes two unary functions and returns a unary function that calls them both.

1 | composeu(double, square)(3) // 36 |

## Solution

1 | function composeu (f, g) { |

#### ✔️ Write a function `composeb`

that takes two binary functions and returns a function that calls them both.

1 | composeb(add, mul)(2, 3, 5) // 25 |

## Solution

1 | function composeb (f, g) { |

#### ✔️ Write a function that allows another function to only be called once.

1 | add_once = once(add) |

## Solution

1 | function once (func) { |

#### ✔️ Write a factory function that returns two functions that implement an up/down counter.

1 | counter = counterf(10) |

## Solution

1 | function counterf (value) { |

#### ✔️ Make a `revocable`

function that takes a `nice`

function, and returns a `revoke`

function that denies access to the nice function, and an `invoke`

function that can invoke the nice function until it is revoked.

1 | temp = revocable(alert) |

## Solution

1 | function revocable (nice) { |

## Monads & Gonads

### Axioms

1 | // 1 |

### The Identity Monad

1 | function MONAD () { |

How you call it:

1 | var unit = MONAD() |

### The Ajax Monad

#### This tow are equivalent.

1 | // monad.bind(func) |

#### ❓Ajax Monad

1 | function MONAD () { |

**related:**

Object.create()

#### Use Ajax Monad

1 | var ajax = MONAD().lift('alert', alert) |

### ❓The Maybe Monad

`NaN`

: If you divide 0 by 0, you got `NaN`

, instead of throw.

#### Maybe Monad

1 | function MONAD (modifier) { |

#### Use Maybe Monad

1 | var maybe = MONAD(function (monad, value) { |

### The Promise Monad

#### Make a vow

1 | var my_vow = VOW.make() |

#### Promise Monad

1 | var VOW = (function () { |

1 | make: function make () { |

1 | function herald (state, value, queue) { |

1 | promise: { |

1 | function enqueue(queue, func, resolver, breaker) { |

1 | function enlighten (queue, fate) { |