Proceedings of Extreme Markup Languages®

Higher-Order Functional Programming with XSLT 2.0 and FXSL

Dimitre Novatchev

Abstract

This article describes the added support in FXSL 2.0 for writing
higher-order functions in XSLT 2.0 based on new fundamental
XPath 2.0/XSLT 2.0 features such as the sequence datatype,
strong typing and writing functions natively in XSLT.
FXSL 2.0 makes nearly all standard XPath 2.0/XSLT 2.0 functions
and operators higher-order by providing in the FXSL namespace
the definition of their identically named higher-order wrappers
and partial applications. The author argues that in effect,
this makes XSLT 2.0 + FXSL a higher-order strongly-typed functional
programming system.

This paper demonstrates how based on the even higher degree of
abstraction and code reuse many challenging problems have now
more compact or even one-line solutions.

Dimitre Novatchev

Dimitre Novatchev is known as the developer of the FXSL functional programming library for XSLT, the popular XPath Visualizer
tool and EXSLT for MSXML4.
He works in the Data Programmability team
at Microsoft.

Higher-Order Functional Programming with XSLT 2.0 and FXSL

Extreme Markup Languages 2006® (Montréal, Québec)

Introduction

XSLT has turned out to be very different from the typical programming
languages in use today. One question that’s being asked frequently is:
What kind of programming language is actually XSLT?
Until recently,
the authoritative answer from some of the best specialists was that
XSLT is a declarative (as opposed to imperative), but still not a FP
[functional programming], language. Michael Kay notes in his article
“What kind of language is XSLT” [Kay]:

Although XSLT is based on functional programming ideas, it is not
as yet a full functional programming language, as it lacks the
ability to treat functions as a first-class data type.

My Extreme 2003 paper
“Functional Programming in XSLT using the FXSL
Library” [Nova5] described
a way to implement higher-order functions in XSLT 1.0 and demonstrated
the XSLT implementation of some of the most general FP design patterns.

This article goes further.
It shows how the new features of XSLT 2.0 and XPath 2.0 make it even
easier to write higher-order native xsl:functions that are compact and
type-aware, and how otherwise complex processing tasks can now be
implemented as one-liner XPath 2.0 expressions. What is more, even
the standard XPath 2.0/XSLT 2.0 functions and operators
[F & O], [XSLT2.0] have been turned
into their higher-order-function equivalents.

Basic definitions

For readers not familiar with the basic functional programming concepts,
some definitions and brief descriptions are provided below.

Imperative programming

The imperative style of programming describes a system as
evolving from an initial state through a series of state
changes to a set of desired final states. A program consists
of commands that change the state of the system. For example,

y = y - 2

will bring the system into a new state, in which the variable
y has
a new value, which has been obtained by subtracting
2 from the value of y in the
previous state of the system.

Declarative programming

The declarative programming style specifies relationships
between different variables,
e.g., the equation

z = y - 2

declares z to have a value of two less than the
value of y.

Variables, once declared, cannot change their value. Typically,
there is no concept of
state, order of execution, memory,
..., etc.

Functional programming

A function is a relationship between a set of
inputs and an
output.
It can also be regarded as an operation, which when passed
specific values as input produces a specific output.

A functional program
is made up of a series of definitions
of functions and other values [ThompSJ].

The functional programming style builds upon the declarative
programming style by adding the ability to treat functions
as first-class objects — that means, among other things,
that functions can be passed as arguments to other functions.
A function can also return another function as its result.

Basic Haskell notation

In the rest of this article, the following notations are
borrowed from the programming language Haskell
[ThompSJ], [JonesSP]
and are used to show an abbreviated version of the XSLT code.

Function definition

f :: Int -> Int -> Int -> Int

f x y z = x + y + z

is the definition of a function f having arguments
x, y, and z and producing
their sum. The first line in the definition is an optional
declaration of the type of the function. It says that f
is a function, which takes three arguments of type Int
and produces a result of type Int. The type of f
itself is:

Int -> Int -> Int -> Int

Function application

f x y z

is the application of the function f to the arguments
x, y, and z

Lists

[a1, a2, a3]

is the list of elements a1, a2, a3.

[ ]

is the empty list.

xs

by convention should be a variable, which is a list of elements of type x

x:xs

is an operation which pre-pends an element x
in front of a list xs

In a list x:xs the symbol x denotes the
head and
xs denotes the tail
of the list. Operating on the head and
tail is useful in defining list-processing functions recursively.

HOF [Higher-Order Functions]

A function is higher order
if it takes a function as an argument or returns a function
as a result, or both
[ThompSJ].

Examples.

A classical example is the map
function, which can be defined in Haskell in the following two ways:

map f xs = [ f x | x <- xs ] (1)

or

map f [ ] = [ ]
(2)
map f (x:xs) = f x : map f xs

In this definition | means "such that"
and <- means "belongs to".
: is the cons operator
— this prepends an element at the start of a list.

The map function takes two arguments — another function
f
and a list xs.
The result is a list, every element of which is the result of
applying
f
to the corresponding element of the list
xs.

The last two examples show how easy and convenient it is to produce
new functions from a more general higher order function, simply by
feeding it with different function-arguments.

Whenever XSLT programmers try to do without higher order programming, then
they repeatedly have to write similar recursive processing code
(e.g. calculating product, maximum, minimum, etc.);
this wastes programming effort each time an instance of such code is written, and means
whenever a change is made, it has to be replicated in many locations — this is very error-prone and
often becomes a maintenance nightmare.

Higher Order Functions and XSLT

A simple analysis shows that there’s nothing like higher-order
functions in XSLT. In XSLT 1.0 even the notion of writing one
own’s function is not supported natively.

XSLT 2.0 provides the xsl:function instruction;
now programmers can write their functions natively in XSLT.
However, it is still not possible to pass an
xsl:function as a parameter to another callable
component and then invoke it dynamically.

Therefore, as a start, we have to define what is to be considered
a higher order function in XSLT. Then, we will describe a
mechanism that allows “handles” or “references” to such functions
to be passed to other functions, or returned by functions.
Finally, we show how to write an xsl:function so
that it can be passed as a parameter in a most convenient and
intuitive way.

Higher-Order Functions in XSLT 1.0

XSLT 1.0 templates come closest to the definition of functions.
Templates accept parameters and produce what can be regarded
as a single result. Not all types of templates, however, can
have references that are intuitive and easily represented.
An example is a named template without a
"match" attribute. The following is illegal in
XSLT:

<xsl:call-template name="$varName"/> WRONG!

A template name should be a QName and so is the value of the
"name"
attribute of xsl:call-template[XSLT1.0].
A QName is static and must be completely specified — it
cannot be dynamically produced by the contents of a variable. An XSLT processor
produces a compile-time error.

Template References

Another way to instantiate a template dynamically has been known for
quite some time [HainesC], but there was no evidence of
using it in a systematic manner before 2002. Let's have a template, which matches
only a single node belonging to a unique namespace. We'll call such
nodes
“nodes having a unique type“
or
“template references”:

We have defined two templates, each matching only a node of a unique
type. The first template produces twice the value of its input
parameter pX. The second template produces the value of its
input parameter pX multiplied by 5.

Now we'll define in another stylesheet a template (let’s think
of it as the apply-and-sum-two-functions template)
that accepts as
parameters references to two other templates
(template references),
instantiates the two templates that are referenced by the
template-reference parameters, passing as parameter to each
instantiation its pX parameter, then as result it
produces the sum of the outputs of these instantiated templates.

The result produced when this last stylesheet is applied on any
(ignored) xml source document, is:
21

What we have effectively done is we called the template named
"sum2Functions",
passing to it two
references to templates,
that accept a pX parameter
and produce something out of it.
The "sum2Functions" template successfully
instantiates (applies) the templates that are uniquely identified by the template reference parameters, then finally
produces the sum of their results. What guarantees that the XSLT processor will select exactly the necessary templates is
the unique namespace-uri of the nodes they are matching. The most important property of a template reference is that it guarantees
the unique matching of the template that it is referencing.

Higher-Order Functions in XSLT 2.0

In XSLT 2.0 the programmer can define functions written
natively in XSLT using the new xsl:function
instruction.
Functions defined in this way can declare their return
type and the types of the parameters they accept. It is
legal to have different overloads (xsl:functions
defined
with the same name) as long as they have different number
of parameters.

However, there’s no obvious way to pass an
xsl:function as a parameter. The following
XPath 2.0 expression is illegal:

$varFunc($params) (: WRONG! :)

According to the latest XSLT 2.0 Candidate Recommendation
[XSLT2.0] the value of the name attribute
of xsl:function must be a QName – static and
completely specified at compile time – it cannot be
dynamically produced by the contents of a variable.
An XSLT 2.0 processor produces a static (compile-time) error.

someFunction(funcName(), otherParams) (: Not what we wish! :)

In the call of someFunction() above the first
parameter is not the function funcName()
itself, but the value of a function funcName()
that is defined to have zero arguments.

Once again template references come to help.

We can write an XSLT 2.0 xsl:function that
accepts as a parameter a template reference.
The most important such function is f:apply().
It invokes its first argument via templates application,
passing all its remaining arguments as parameters:

What have we achieved so far? We managed to replace a clumsy –
looking 5-line xsl:call-template used in the
XSLT 1.0 version with a simple one-line XPath expression:

f:applyAndSum($vfunTwice, $vfunFiveTimes, 3)

However, we are still passing explicit template references as
parameters – could we do better? Could we write
xsl:functions (not templates!) that do
the Twice and FiveTimes processing and then pass “something
similar to” these xsl:functions’
names as parameters to the called function?

Ideally, we wish to be able to invoke f:applyAndSum()
in the following way:

f:applyAndSum(f:funTwice(), f:funFiveTimes(), 3)

where funTwice() and funFiveTimes()
are xsl:functions (not templates) of
one argument.

It turns out that this can be done. We write funTwice()
and funFiveTimes() in the usual way:

Note the use of the mode attribute: mode="f:FXSL"
In case our template references were not in a specific mode
(either no mode was specified or mode="#default" was used, and
the <xsl:apply-templates> instruction to select them also
didn't specify a particular mode, then it would be very easy for
the template-reference-nodes to be processed by completely unexpected
templates selected for processing simply because of their generality and
higher import precedence, such as <xsl:template match="node()">.

Standard Higher Order XPath
2.0 Functions

The result so far is very useful – from now on we can write all
our xsl:functions as higher-order
functions in the way described above.

However, there are many functions we didn’t write – the most
useful ones being the standard XPath 2.0 Functions and
Operators [F & O] and the standard XSLT 2.0
functions [XSLT2.0]. We could benefit greatly
from being able to treat these functions as first class objects
of the language in solving many real-world problems.

Fortunately, exactly the same approach can be used to create a
higher-order function with the same name (but in another
namespace) as any given function. The code below shows how
this has been done with the avg() function.

Standard Higher Order XPath 2.0 Operators

Using exactly the same approach we can make higher-order
any standard XPath 2.0 Functions and Operators[F & O]
operator. The code below shows how this has been done with the
op:numeric-multiply() — the "*" operator.

Because of the strict type-checking in XPath 2.0 many
situations arise, when in order to avoid a type error we must
explicitly convert the arguments of a function to instances of
the mandated type. In other cases, in order to preserve a
desired degree of accuracy we may prefer to use a more strict
argument type rather than the more general default type
accepted by a function. For example, in many cases evaluating
the following expression:

sum(/*/claim/claim_line/reimbursement_amount)

may produce more inaccurate results (because all items in the
argument-sequence of sum() are cast to
xs:double) than evaluating the corresponding
expression where the elements to be summed are first converted
to xs:decimal:

sum(f:map(f:decimal(),
/*/claim/claim_line/reimbursement_amount)
)

If the above two expressions were evaluated against the
following xml document, with a given XSLT 2.0 processor such as Saxon 8.7.1,
they would produce, correspondingly,
343.24999999999992 and 343.25

Higher Order Foreign Functions

The attentive reader may already have observed that the approach
used to represent a non-higher order function by using an identically named
higher-order wrapper can seamlessly be extended to functions defined and
implemented outside the scope of XPath2.0/XSLT2.0, such as any
extension function of interest.

Representing lists in XSLT

Many functional programming design patterns involve operations on lists.
Therefore, we have to choose a representation of a list in XSLT.

We represent in XSLT 1.0 a list of N
elements [x1, x2, …, xN] as the following tree:

<list>
<el>x1</el>
<el>x2</el>
. . . . . . . .
<el>xN</el>
</list>

where any names may be chosen for “list” and “el”.

As a special case, when xi are lists themselves we get
the following representation of a
list of lists:

A list of characters
is most naturally represented as a string. Therefore, for each design
pattern, which operates on lists there will be two implementations –
one for lists represented as node-sets and one for lists of characters
represented as strings.

The XPath 2.0 Data Model [XPath2] used in XSLT
2.0 provides a new data type — the
sequence. The sequence data
type makes it possible to represent any type of list, not only
list of nodes — it is the natural way of representing
lists in XSLT 2.0. However, the sequence type is flat,
meaning that an item of a sequence cannot be a sequence itself.
Therefore, the way to represent a list of lists is still the one
described for XSLT 1.0 above.

FP Design Patterns

Based on the XSLT1.0/2.0 implementation of HOF, described above,
we describe now the XSLT implementation of some of the most
general FP design patterns [RalfL].

Recursion patterns

Recursion design patterns capture some of the most general and
frequent uses of recursion.

Iteration

The iter function implements this design pattern.
It is briefly defined in Haskell like this:

The iter function is defined using
guards — boolean expressions
used to express various cases in the definition of a function.
Here the "." operator denotes functional composition:

(f.g) x = f(g x)

The id function is the identity — id x = x.

As defined, iter takes a non-negative integer
n and a function f and returns another
function, which is the composition of f with itself
n-1 times. Functional composition is another FP design
pattern to be discussed later.

Here’s the corresponding XSLT 2.0 implementation (note that it is based on a DVC
(Divide and Conquer) approach in order to avoid stack overflow with some XSLT 2.0
processors that may not optimize tail-recursion well):

We’ll show f:iter() in an example later in this
paper, when we discuss and demonstrate currying and partial
application.

Recursion over a list (folding)

The function sum that computes
the sum of the elements of a list can be defined as follows:

sum [] = 0

sum (n:ns) = n + sum ns

The function product that
computes the product of the elements of a list can be defined
as follows:

product [] = 1

product (n:ns) = n * product ns

There is something common and general in the above two function
definitions — they define the same general operation over a list,
but provide different arguments to this operation.
The arguments to the general list operation are displayed in bold
above.

They are a function f
(+ and
*
in the described cases) that takes two arguments and
an initial value (0
and 1 in the
described cases) to use as a second argument when
applying this function to the first element of the list.
Therefore, we can define this general operation on lists
as a higher-order function:

foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs

foldl processes a
list from left to right. Its dual function, which
processes a list from right to left is
foldr:

foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs)

We can define many functions just by feeding
foldl (or foldr)
with appropriate functions and null elements:

On each <sale> element we need to perform two
actions: get a list of all its children, get the product of these
children. Finally, we must sum all results obtained this way on
any <sale> element. We calculate the sum of products with the
following XPath expression:

sum(f:map( f:compose(f:product(), f:childElements() ),
/*/sale
)
)

In this case the result is: 7.56

The function f:compose() is the functional
composition function – it is defined later in this article. It
takes two functions as arguments and produces a new function,
which is their functional composition.

We must note that XPath 2.0 provides a kind of mapping construct
that can be applied on the last location-step of an XPath
expression. The above expression could be re-written in a more
compact form as:

sum(/*/*/f:product(*))

Unfortunately, XPath 2.0 does not provide a mapping construction
for any other kind of a sequence, for example the following is
illegal:

(1 to 10)/f:square() (: Illegal! :)

In all such cases one has to use the f:map() function.

Functional composition and currying (partial application)

Some of the most important FP design patterns deal with producing
new functions from existing ones.

Here we’ll define functional composition and partial application.

Functional composition

The definition of functional composition is as follows:

Given two functions:

g :: a -> b and f :: b -> c

Their functional composition is defined as:

(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)

This means that given two functions f
and g, (.) glues them together by applying
f on the result of applying g.

(.) is completely polymorphic, the only constraint on
the types of f and g being that the type
of the result of g must be the same as the type of
the argument of f.

Functional composition is one of the most often used ways of
producing a new function by applying two other functions in a
successive pipe-like manner.

Curried functions

There are two ways of looking at a function that has more
than one argument. For example, we could have:

f(x, y) = x * y (1)

or

f x y = x * y (2)

The first expression above defines a function that takes
a pair of arguments and
produces their product.

In contrast, the second definition allows the function f
to take its arguments one at a time. It is perfectly legal to have
the expression:

f x

Not providing the second argument in this concrete case results
in a new function g (g = f x) of one argument
y, defined below:

g y = x * y

Defining a function as in (2) has the following advantages:

A uniform style for expressing function application
over one or many arguments - we write:

f x, f x y, f x y z, ... etc.

The ability to easily produce partial functions, resulting from
applying a function only on the first several of its arguments.
For example, we can also define the function g
above as (x *) — a partial application of
multiplication, in which the first argument has been bound to
the value x.

A function as defined in (2) can be regarded as having
just one argument x, and returning a function of y.

Functions defined as in (2) are called
curried functions after Haskell Curry,
who was one of the developers of the lambda calculus
[ChurchA],
and after whom the Haskell programming language was named.

Functions defined as in (1) are called uncurried.
Uncurried functions can be turned into curried ones by the
curry function, and curried functions can be turned into
uncurried ones by the uncurry function.
Here's how curry and uncurry are defined
in the Haskell Prelude:

curry f x y = f(x,y)
uncurry f (x, y) = f x y

Partial applications

A partial application is a function
returned by any application of a curried function on the first several,
but not all of its arguments. For example:

incr = (1 +)
double = (2 *)

As defined above, incr is a function that adds one to its
argument, and double is a function that multiplies its
argument by 2.

Partial application in the special case when the function is an operator
is called an operator section.
(1 +) and (2 *) above are examples of
operator sections.

Using partial applications it is possible to simplify considerably many
function definitions, which results in shorter, simpler, more
understandable and maintainable code. For example, instead of defining
sum and product as:

sum xs = foldl (+) 0 xs
product xs = foldl (*) 1 xs

it is possible to define them in an equivalent and much simpler way by
omitting the last identically-named argument(s) from both sides of
the definition:

sum = foldl (+) 0
product = foldl (*) 1

Producing partial applications is one of the most flexible and
powerful ways of creating new functions dynamically.

The xsl:functionf:compose() has three
parameters, two of which are the functions to be composed —
pFun1 and pFun2 — and the third is the
argument arg1, on which pFun2 will be
applied.

In many cases, there are more than two functions that should be
successively applied, each using as its argument the result
returned from the previous function. In any such case, it would
be inconvenient or even impossible (e.g., the number of functions
to be composed is not known in advance) to compose the functions
two at a time.

Therefore, we also provide the definition of a function, which
takes two arguments: a list of functions and an argument on
which the last function in the list is to be applied. This
function produces the result of the functional composition of all
functions in the list, using the provided initial argument:

The expressions f:mult(3) and f:mult(2)
are partial applications of the multiplication operator
f:mult(). Essentially, they are functions of one
argument, which return their argument multiplied, respectively,
by 3 or by 2. We will describe the XSLT 2.0 implementation of
currying and partial applications in the next section.

Implementation of currying and partial application in XSLT 2.0

The examples in the previous section demonstrated the
importance of being able to use partial applications of
functions. Below, we provide an XSLT implementation of
currying and partial application. Let’s recall the definition
of curry:

curry f x y = f(x,y)

This means that curry f returns a (curried)
function of two arguments, and curry f x returns
a function of one argument.

We have implemented a more generalised version of curry, which accepts
a function of N (two or more) arguments and allows the first
k (k < N) arguments to be specified, so that the result will be a
partial application of the function passed as the first argument.

Our XSLT implementation of curry should,
therefore, do the following:

Keep a reference to the function f.
This will be needed if all arguments are passed and the
value of f (as opposed to a partial
application function) must be calculated.

Keep a record of the number of arguments of f.
This is necessary, to know when all arguments for the
function have been specified so that the function will be
evaluated.

Provide a reference to an internal generic
f-curry function that will record and
accumulate the passed arguments and, in case all
arguments have been provided, will apply (the function
being curried) f on them and return the
result. In case not all arguments’ values have yet been
provided, then f-curry will return a variant
of itself, that knows about all the arguments’ values
accumulated so far.

The XSLT 2.0 implementation of f:curry and
partial application is presented in the Appendix.

The f:curry function takes a function (a
template reference) and a second argument, which is the
number of the arguments of this function. It also takes up
to ten optional arguments on which the provided function
(the first argument to f:curry) is to be partially
applied.

It then builds its internal f-curry function to
produce the result as a partial application.

The internal f-curry function accepts up to ten
arguments.

All specified arguments are appended to an internal
structure, containing elements with names "arg"
and values — the value specified for the "arg"
argument. For example, if f has 6 arguments and
only the first 3 of them were specified, the
f-curry’s internal store could look like this:

Notice that not only the values of the specified arguments
are recorded, but also their types have been determined and
for a sequence-argument this is done on all items of the
sequence. A new FXSL function: f:type() is used
to determine the type of any argument or (in the case of a
sequence-argument) the type of its items.

Below is the most essential code that produces the result of
f:curry() when not all arguments have been
specified:

Whenever values for all arguments are provided, the
implementation instantiates the template that implements the
fun function (the function being curried) — the
template reference to it is stored in the <fun>
element.

Then the argument values are constructed in their proper type by
using the stored raw values and the type information for
every argument or item of an argument-sequence. A companion
function of f:type() – f:Constructor()
is used in this process.

The code of the internal function int:getArg()
that reconstructs an argument is listed below:

Let’s see how f:curry can be used. In the next
example, we curry the f:mult() multiplication
operator (introduced earlier in this paper) specifying one
argument’s value – 3. The result is a function of one
argument that multiplies it by 3.

So, this expression:

f:apply(f:curry(f:mult(),2,3), 5)

produces the wanted result: 15.

As useful as this is, we’d like to hide the use of
f:curry() and to achieve a more elegant and
compact way of expressing partial applications.

This can be elegantly accomplished by defining a new overload
of f:mult(), which takes one argument and returns
the partial application, in the following way:

In FXSL 2.0 the definition of all possible partial
applications has been specified for all standard XPath 2.0
functions and operators, with some very few exceptions.
Listed below are some examples of the power of using
higher-order functions and their partial applications:

Limitations of wrapping non-higher order functions

There are just a very few limitations to the powerful
approach of wrapping an existing function by an identically
named higher-order wrapper:

Functions with unknown number of arguments

The standard XPath function concat() accepts any number of arguments. Passing a reference
to this function is not useful for any practical purposes.

Functions with zero number of arguments

Functions with zero number of arguments cannot be curried. Also,

f:zeroArgsFun()

should not be confused with

zeroArgsFun()

While the first evaluates only to a reference to the function, the second evaluates to
the result of the original non-higher order function.

This can actually be useful when we want to accomplish delayed (lazy) function evaluation,
for example, to prepare a list of functions to be evaluated by another function.

Functions having overloads

When an xsl:function has overloads, a wrapper can be provided only for one
of this non-higher order function. If two overloads are:

F(arg1, arg2, ..., argN)

and

F(arg1, arg2, ..., argK)

where N > K

and we have created a wrapper f:F() for the first overload (having N arguments), then
the expression

f:F(arg1, arg2, ..., argK)

should not be confused with evaluating the second overload via the wrapper. In fact,
this expression denotes the partial application of the first wrapped overload on its first K
arguments.

It is still possible to provide a wrapper for the second (or any other existing) overload,
but the name of every wrapper must be different (at least by namespace).

Type detection for arguments of user-defined type

The argument type-detection that f:curry() uses has been implemented only
for the builtin XML Schema datatypes. It will not recognize the user-defined type of an argument,
which can be created by an user of a Schema-Aware (SA) XSLT 2.0 processor.

FXSL 2.0

This article is only a brief reflection of the work
accomplished in the development of the FXSL 2.0 — a functional
programming library for XSLT 2.0 [FXSL].

While it incorporates the existing FXSL 1.X library for
functional programming with XSLT 1.0, FXSL 2.0 provides a new
and strong support for such fundamental XPath 2.0/XSLT 2.0
features as the sequence datatype, strong typing, writing
functions natively in XSLT. FXSL 2.0 makes nearly all standard
XPath 2.0/XSLT 2.0 functions and operators higher-order by
providing in the "http://fxsl.sf.net/" namespace
the definition of their identically named higher-order wrappers
and partial applications.

Additionally, FXSL 1.X, which is incorporated in FXSL 2.0,
provides an XSLT implementation of all the major FP design
patterns described in this paper and, based on them, goes
further to provide more specific functionality. The home site
of FXSL contains materials, describing the implementation of:

Fundamental functions on lists and trees as well as some
numerical methods [Nova1].

Implementation of a mechanism (closely matching the "Monad
someType" class) for using reliably functions with side
effects

Conclusion

More than three years ago FXSL 1.0 challenged our understanding
about XSLT programming by providing the definition and
implementation of basic FP design patterns and making it much
easier to solve a large class of problems that until then had
been considered very difficult or not appropriate for XSLT.

The next generation of FXSL adds support for new fundamental
XPath 2.0/XSLT 2.0 features such as the sequence datatype,
strong typing and writing functions natively in XSLT.
FXSL 2.0 makes nearly all standard XPath 2.0/XSLT 2.0
functions and operators higher-order by providing in the
"http://fxsl.sf.net/" namespace the definition
of their identically named higher-order wrappers and partial
applications.