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

## A constant function

## An identity function

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

map, foldr, foldl, See also Folds

partially - partial application

See also Bootsrapping Folds

**Note:**See TracWiki for help on using the wiki.