First class functions and currying
The paradigm behind functional programming says that everything can be solved creating and combining functions. Mathematical functions that is, like in "a transformation that takes values from a domain and map them to a codomain". For example, the domain of the length function is the set of all possible character strings and its codomain are the positive integers, the sin function has as domain all the angles and as codomain the reals between -1 and 1. A couple of function definitions in F#:
let square n = n * n
let cube p = p * p * p
With this definitions square 5 gives 25 and cube 3 is 27. While at it, it's worth noting that the type of square is int -> int, which is the F# way of saying that the domain of square is all the integers and so is its codomain. Furthermore, in languages like F# or Haskell functions are first class citizens or, for short, they have first class functions. Among other things, this means that a function can be used in any place where any other value (be it an integer, a double, a string, etc.) can. For example, a function can be passed as argument or it can be returned from a call or it can be the result of an expression. To see where this fact can leads us to, let's consider this generalization of square and cube:
let rec raise power value = if power = 0 then 1 else value * raise (power - 1) value
The raise function defines value ^ power based on the facts that value ^ 0 = 1 and value ^ power = value * (value ^ (power - 1)). The type of raise is int -> int -> int, intuitively, this says that raise takes two integers and produces a third one. But the type of raise can also be interpreted like this: int -> (int -> int), that is, its domain is the integers and its codomain are the functions of type int -> int. Say what? Well, for example, raise 10 doesn't give any number but a function, and sure enough, if we ask F# to evaluate raise 10, it does it without a glitch, and instead of printing a number it explains that the result is a function of type int -> int. This interesting fact let us make these definitions:
let square = raise 2
let cube = raise 3
That is, the square function is equivalent to the raise function with its first argument fixed at 2. We just defined a new function from another function to which we did *not* give all its arguments! This operation of invoking a function with only a part of its arguments is called partial application or currying, after Haskell Curry. square and cube are silly examples of the power and elegance that we can attain with F#, with any luck I'll show you more practical examples in future posts.
Intriguing but terribly irrelevant? May be not so: the upcoming versions of C# and VB.NET will be able of currying all right. Something nice is cooking at Orcas.