Higher-Order Functions

This page present some higher-order functions of the XQuery specification. The BaseX-specific Higher-Order Functions Module contains some additional useful functions.

=Function Items=

Probably the most important new feature in XQuery 3.0 are function items, i. e., items that act as functions, but can also be passed to and from other functions and expressions. This feature makes functions first-class citizens of the language. The XQuery 3.0 page goes into details on how function items can be obtained.

Function Types
Like every XQuery item, function items have a sequence type. It can be used to specify the arity (number of arguments the function takes) and the argument and result types.

The most general function type is. It's the type of all function items. The following query for example goes through a list of XQuery items and, if it is a function item, prints its arity:

 for $item in (1, 'foo', fn:concat#3, function($a) { 42 * $a }) where $item instance of function(*) return fn:function-arity($item) Result:

The notation for specifying argument and return types is quite intuitive, as it closely resembles the function declaration. The XQuery function

 declare function local:char-at( $str as xs:string,  $pos as xs:integer ) as xs:string { fn:substring($str, $pos, 1) };

for example has the type. It isn't possible to specify only the argument and not the result type or the other way round. A good place-holder to use when no restriction is wanted is, as it matches any XQuery value.

Function types can also be nested. As an example we take, which takes a function defined on single items and makes it work on sequences as well:

 declare function local:on-sequences( $fun as function(item) as item* ) as function(item*) as item* { fn:for-each($fun, ?) };

We willl see later how  works. The type of  on the other hand is easily constructed, if a bit long:

.

=Higher-Order Functions=

A higher-order function is a function that takes other functions as arguments and/or returns them as results. and  from the last chapter are nice examples.

With the help of higher-order functions, one can extract common patterns of behavior and abstract them into a library function.

Sequences
Some usage patterns on sequences are so common that the higher-order functions describing them are in the XQuery standard libraries. They are listed here, together with their possible XQuery implementation and some motivating examples.

Folds
A fold, also called reduce or accumulate in other languages, is a very basic higher-order function on sequences. It starts from a seed value and incrementally builds up a result, consuming one element from the sequence at a time and combining it with the aggregate of a user-defined function.

Folds are one solution to the problem of not having state in functional programs. Solving a problem in imperative programming languages often means repeatedly updating the value of variables, which isn't allowed in functional languages.

Calculating the product of a sequence of integers for example is easy in :

 public int product(int[] seq) { int result = 1; for(int i : seq) { result = result * i; } return result; }

Nice and efficient implementations using folds will be given below.

The linear folds on sequences come in two flavors. They differ in the direction in which they traverse the sequence: