**function(groovy) #3**

If all you have is a hammer, everything looks like a nail.

*Abstract: The Groovy closure can be the return value from a method or another closure. This idea eases us into the world of higher order functions: functions that accept functions as parameters or return functions as their result. Functions as parameters is the key feature of the next blog. Functions as return values introduces the notion of currying and increasing the adoption of functions with only a single parameter.*

Ken Barclay

kenbarc@googlemail.com

**Previous**: The Groovy closure

**Resources**: Chapter 12 Higher Order Functions

**Advanced closures**

A
single function definition can effectively define a complete family of
functions. Having defined the parent function, we are able to specialize from
this single parent a number of related functions. To achieve this we use the
notion of

*currying*, named after the mathematician Haskell Curry. This idea is generally unfamiliar to the imperative programmer but is one worth getting acquainted with.
Example
3.1 demonstrates how the

**Closure**class method**curry**is used to achieve the effect of currying. Closure**multiply**expects two parameters and returns their product. If we curry this function with the value 2, then we have created a new function which doubles its single parameter. Sensibly we choose to refer to this as**twice**. Equally, if we curry**multiply**with the value 4, then we have the closure**quadruple**. Both are functions of one parameter and can be used directly, or are candidates for use with any other function.**Example 3.1**:

*Curried closure*

// multiply:: Integer * Integer ->
Integer

final
multiply = { final int x, final int y -> x * y }

// twice:: Integer -> Integer

final twice
= multiply.curry(2)

// quadruple:: Integer -> Integer

final
quadruple = multiply.curry(4)

assert
twice(5) == 10

assert
quadruple(5) == 20

The
type signature informs us that

**multiply**is a function which when given a pair of integers will return their product. If then we were able to call function**multiply**and give only one actual parameter, then we would get a result which is itself another function. For example, if we could call**multiply**with the parameter 2, then effectively the first formal parameter**x**is replaced throughout the definition for**multiply**with this value. Further, since the value for the parameter**x**is now specified, then this formal parameter can be removed from the definition. We then effectively produce the function:
{ final int y ->
return 2 + y }

one
that takes a single numeric parameter and returns 2 times its value. This function
is the value bound to the identifier

**twice**.
Since
a Groovy closure is an object and a Groovy closure can return a closure, then
currying can be achieved through another route. In Example 3.2 we have defined
a closure

**add**which takes a single parameter**x**and returns a closure. The returned closure is defined both in terms of its own parameter (y) as well as x, sometimes described as a*free variable*when used in this manner.**Example 3.2**:

*Alternative currying*

// add:: Integer -> Integer ->
Integer

final add =
{ final int x ->

return { final int y -> x + y }

}

// successor:: Integer -> Integer

final
successor = add(1)

assert
successor(5) == 6

assert
successor(successor(5)) == 7

In
Example 3.2 the call add(1) delivers a closure that is bound to the

**successor**identifier. In that closure the free variable**x**has been fixed as the value 1.
Interestingly
function

**add**expects a single parameter and delivers a function. That function also expects a single parameter and delivers some result. As shown we are able to support currying without using the**curry**method. It also moves us to adopting the notion of functions only ever taking one parameter.
Why?
Well first we get currying for free. Second, it greatly enhances our capacity
to compose functions. Function composition in the previous blog expected them
to operate with only a single parameter.

Suppose
we want to develop a curried version of a binary function

**f**which is*uncurried*and of the type A * B -> C. This binary function**f**expects its parameters as a pair but its curried version will apply them sequentially. We therefore have to form them into a pair before applying**f**to them. The function**C**does exactly this:
// C:: (A * B -> C) -> A -> B
-> C

final C = {
f -> { a -> { b -> f(a, b) }}}

Again,
the signature reveals what is happening. Function

**C**expects a function as its first parameter. That parameter function has the signature A * B -> C, an uncurried binary function. Function**C**returns the curried function with the signature A -> B -> C, as required. We can use**C**where we need to transform an uncurried binary function into its curried form.
Example 3.3 introduces function

**C**and its complementary function**U**. Using**U**we convert the curried**mul**function into it uncurried equivalent,**mulU**. Using**C**we transform the uncurried**mulU**function into its curried equivalent,**mulC**.**Example 3.3**:

*Curried/uncurried transformation*

// mul:: Integer -> Integer ->
Integer

final mul =
{ final int x -> { final int y -> x * y }}

// U:: (A -> B -> C) -> (A * B)
-> C

final U = {
final f -> { final a, final b -> f(a)(b) }}

// mulU:: (Integer * Integer) -> Integer

final mulU
= U(mul)

assert
mul(3)(4) == 12

assert
mulU(3, 4) == 12

assert
U(mul)(3, 4) == 12

// C:: (A * B -> C) -> A -> B
-> C

final C = {
final f -> { final a -> { final b -> f(a, b) }}}

// mulC:: Integer -> Integer ->
Integer

final mulC
= C(mulU)

assert
mulC(3)(4) == 12

Various factory design patterns are used throughout
OO-land. The earlier examples showed currying as a mechanism for developing a
family of functions from a single definition. In effect currying is a form of

*factory for functions*.
Many
of the emerging examples do not exploit Groovy meta-programming capabilities.
They also make ever greater demands on the types of quantities, including our
function parameter and return types. This work makes a strong case for a Groovy
static type checker.

## No comments:

Post a Comment