Prolog/Higher Order Programming

Introduction
Higher-order programming means writing programs that take other programs as input and/or return still other programs as output. Higher-order programming is common in functional programming, but can be in done in Prolog as well.

As an example, suppose you are writing a speech synthesis application that reads out phone numbers aloud. We might have a predicate  that relates Prolog integers 0 through 9 to English words (as symbols):

Now, to translate a phone number, define:

Now, suppose we want to add support for another language, say, German. You define :

To translate a phone number, use :

Note the common recursion pattern in  and. You've probably seen that many times before, even written it several times. It can be summed up as:


 * Base case: relate the empty list to itself.
 * Recursive case: relate the first element of the first list to the first element of the second via some predicate, then recur on the tails of both lists.

This pattern can be captured by a higher-order predicate generally known as  (but not defined by standard Prolog):

In Prolog, we cannot write P(X,Y) since the head of a functor must be a symbol. Therefore, we use the infix operator  that unifies its first argument with a term built from its right argument, which must be a list. The first element, which must be a symbol, becomes the functor, the rest its arguments. We then apply  to the term we constructed to invoke it as a Prolog goal. Note that many Prolog implementations also define,  , ... built-in predicates which construct a callable term out of the given arguments (with the first argument being the principal functor), so that the above code example can be also written as

We can now redefine  and   as:

Both predicates still work in both directions and non-determinism is preserved.

The benefit is obvious: by using, we avoid repeating code fragments so our programs become shorter and easier to read and understand.