Currying
Saturday, January 24th, 2009Predicates are single-argument functions. They can act on another predicate and change its behaviour, but they don’t have any direct ability to act on two or more predicates.
Sometimes this ability is needed. For example, suppose you wish to wish to express concepts such as ‘taller than’, ’shorter than’, ‘quicker than’, and ‘cleverer than’. Clearly there is a common theme to these concepts which allows them to be derived from ‘tall’, ’short’, ‘quick’ and ‘clever’, so it would not be appropriate to implement new atomic predicates for each.
A more generic solution to provide a predicate with the meaning ‘more x than y’. This apparently takes two arguments: the type of comparison to be made, and the entity with which to compare. However, since predicates take one argument only, it cannot be implemented that way.
The restriction on the number of arguments can be circumvented by breaking the problem down into stages:
- the ‘more than’ predicate first acts on x to produce an intermediate form which the meaning ‘more x than’;
- this intermediate form then acts on y to give a final form with the meaning ‘more x than y’.
This technique is called ‘currying‘ (after Haskell Curry, although it had previously been described by Moses Schönfinkel and Gottlob Frege).
In principle there is no limit to the number of arguments which can be handled in this way, or the order in which they are processed. In practice these factors can have a large impact on readability. The number of arguments obviously should be kept as small as possible, because otherwise it will be difficult to remember what they should be. The order of the arguments should be chosen, so far as possible, to make any intermediate forms meaningful in their own right. This makes the meaning of the predicate easier to describe and remember, and avoids creating purely artificial constructs which have no linguistic counterpart.