= 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''.
{{{#!sml
val day = fn 1 => "Monday"
| 2 => "Tuesday"
| 3 => "Wednesday"
| 4 => "Thursday"
| 5 => "Friday"
| 6 => "Saturday"
| 7 => "Sunday"
}}}
{{{#!haskell
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).
{{{#!erlang
-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
{{{#!sml
val curry = fn f => fn x => fn y => f (x, y)
}}}
{{{uncurry}}} transforms a curried function into ''tuple-form''.
{{{#!sml
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
{{{#!erlang
sum(Xs) -> sum(Xs, 0).
sum([], A) -> A;
sum([H|T], A) -> sum(T, H+A).
}}}
== Static typing ==
{{{#!sml
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
{{{#!sml
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).
[wiki:Functions/Map map], [wiki:Functions/Foldr foldr], [wiki:Functions/Foldl foldl], See also [wiki:Folds]
[wiki:Functions/Partially partially] - partial application
-----
See also [wiki:/Bootstrapping8 Bootsrapping] [wiki:/Folds Folds]