Functions are items: substring#2 names the two-argument substring() without calling it, concat(?, ".", ?) is a partial application with two holes, and function-lookup() finds a function by name and arity at run time (or returns (), a portable way to probe a processor). function-name() and function-arity() inspect them, and for-each(), filter(), fold-left(), fold-right(), for-each-pair(), sort() and apply() take them:
xp 'function-lookup(xs:QName("fn:substring"), 2)("abcd", 2)' \
'fold-left(//price, 0, function($sum, $p) { $sum + xs:decimal($p) })' \
'fold-right(1 to 5, "***", concat(?, ".", ?))'function-lookup(xs:QName("fn:substring"), 2)("abcd", 2) => "bcd"
fold-left(//price, 0, function($sum, $p) { $sum + xs:decimal($p) }) => 134.74
fold-right(1 to 5, "***", concat(?, ".", ?)) => "1.2.3.4.5.***"fold-left() sums exactly because the callback casts each price to xs:decimal; fold-right() works from the end, so the stars land last. Use ! for plain loops and these functions when the operation is a parameter.
Higher order Functions
Higher-order functions accept or return other functions — looking up a function by name and arity, inspecting a function item's name and arity, or applying a function across a sequence. See also Custom Functions for user-defined function items.| function-lookup(xs:QName("fn:substring"),2)("abcd",2) | bcd |
| function-name(fn:substring#2) | fn:substring |
| function-arity(fn:substring#3) | 3 |
| for-each(1 to 5, function($a) { $a * $a }) | (1,4,9,16,25) |
| filter(1 to 10, function($a) {$a mod 2 = 0}) | (2,4,6,8,10) |
| fold-left(1 to 5, 10000, function($a, $b) { $a + $b }) | 10015 |
| fold-right(1 to 5, "***", fn:concat(?, ".", ?)) | 1.2.3.4.5.*** |
| for-each-pair(("a", "b", "c"), ("x", "y", "z"), concat#2) | ("ax","by","cz") |
The notation fn:substring#2 refers to the 2-argument overload of fn:substring as a function item, without calling it; ? in an argument position (as in fn:concat(?, ".", ?)) leaves that argument unbound, producing a partially-applied function.
for-each(1 to 5, function($a) { $a * $a })
(1, 4, 9, 16, 25)