# Functions

lambdas, pattern matching and binding symbols to values are essential primitive operations.

## A mapping

A function is another name for a mapping. A function `f` maps (transforms) `Xs` to `Ys`.

Same input, same output. Always. This is, in part, how Referential transparency could be accomplished.

## A lookup table

Given the definitions above, a function could be thought as a lookup table.

```val day = fn 1 => "Monday"
| 2 => "Tuesday"
| 3 => "Wednesday"
| 4 => "Thursday"
| 5 => "Friday"
| 6 => "Saturday"
| 7 => "Sunday"
```
```cost x = case x of
"oranges"   ->  5
"newspaper" ->  8
"apples"    ->  2
```

## Multiple clauses

In some languages a function might have multiple clauses (and multiple bodies).

```-export([cost/1]).

cost(oranges)   -> 5;
cost(newspaper) -> 8;
cost(apples)    -> 2;
cost(pears)     -> 9;
cost(milk)      -> 7.
```

## Single argument and currying

in some languages a function could take exactly one argument (but this argument is a pattern, like n-tuple)

`curry` transforms a fiven function into its curried form

```val curry = fn f => fn x => fn y => f (x, y)
```

`uncurry` transforms a curried function into tuple-form.

```val uncurry = fn f => fn (x, y) => f x y
```

## Pattern matching

for functions it constrains the type or value of the parameter by requiring the parameter to match a given pattern

## Arity

lambdas of different number of arguments in some languages could be bound to the same symbol.

it is a standard idiom in Erlang, Clojure and others to use functions of different arity as auxiliary helper functions

```sum(Xs) -> sum(Xs, 0).

sum([], A) -> A;
sum([H|T], A) -> sum(T, H+A).
```

## Static typing

```datatype t = A | B

fun f x y =
case (x, y) of
(A, A)  => "a, a"
| (A, B)  => "a, b"
| (B, A)  => "b, a"
| (B, B)  => "b, b"
```

syntactic sugar, similar to multimethods

```fun f (A, A)  => "a, a"
| (A, B)  => "a, b"
| (B, A)  => "b, a"
| (B, B)  => "b, b"
```

## Signatures and multi-methods

A set of functions with the same name (binding) but different type-signatures (clauses) is also called multimethods.

Common Lisp (via CLOS), Clojure and Julia have multimethods.

## Classic functions to meditate upon

The point is to realize how the truly declarative style in Haskell (describe what shall be done instead of how to do it) differs from imperative style in Scheme (do this then that - an ordered sequence of steps). This is the power of Pattern Matching - it makes code to look less imperative, encapsulating explicit desctucturing and binding.

Erlang, which is also relies heavily on pattern matching is closer than Scheme to the declarative style of Haskell.

We will use more esoteric notation with explicit lambdas for Scheme and Haskell to respect the tradition and to illustrate all the subtleties (and standard syntax for all other languages).

Haskell, being a "lazy language", uses Normal order of evaluation. Scheme uses Applicative order with explicit lazyness (via macros or the `delay` special form).