diff --git a/Makefile b/Makefile
index 4df9b82..ab7c49e 100644
--- a/Makefile
+++ b/Makefile
@@ -19,12 +19,13 @@
path_src := src
path_test := test
-test_in_apply_gen := $(path_test)/transform/apply-gen-test-in.xsl.apply
+test_apply := $(path_test)/apply/partial-test.xsl.apply \
+ $(path_test)/transform/apply-gen-test-in.xsl.apply
.PHONY: check test
test: check
-check: $(test_in_apply_gen)
+check: $(test_apply)
$(path_test)/runner
%.apply: %
diff --git a/README.md b/README.md
index 150e6ec..996db0b 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,8 @@ functions and XSLT templates that take XSLT as input and produce XSLT
as output.
The system is fully tested---see the test cases for additional
-documentation as this project gets under way.
+documentation as this project gets under way. This README will serve
+as an informal manual until official documentation is produced.
## Higher-Order Functions
@@ -25,8 +26,8 @@ proprietary versions of their software. Others still may wish to
continue using XSLT 2.0.
There are various approaches/kluges for this problem in earlier
-versions of XSLT; this implementation is motivated by Dimitre
-Novatchev's work on [higher-order functions in FXSL][nova-ho].
+versions of XSLT; the basis of this implementation is motivated by
+Dimitre Novatchev's work on [higher-order functions in FXSL][nova-ho].
For example, consider an implementation of a filter function that
accepts a node set and a predicate:
@@ -66,6 +67,33 @@ work is needed. This can be included as part of a build process, and
the output included within a distribution.
+### Partial Applications
+Dynamic function applications using `f:apply` are partially applied if
+the number of arguments provided is less than the arity of the target
+function.
+
+```xml
+
+
+
+
+
+
+
+
+```
+
+The implementation of partial function applications avoids the
+complexity and inaccuracies of [Novatchev's approach][nova-ho] by
+using only sequences, allowing arguments to retain their type and
+context.
+
+
## License
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
diff --git a/src/apply.xsl b/src/apply.xsl
index d7fd6e3..fc184c6 100644
--- a/src/apply.xsl
+++ b/src/apply.xsl
@@ -1,4 +1,4 @@
-
+
-
-
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/apply/arity.xsl b/src/apply/arity.xsl
new file mode 100644
index 0000000..5e9de23
--- /dev/null
+++ b/src/apply/arity.xsl
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/apply/partial.xsl b/src/apply/partial.xsl
new file mode 100644
index 0000000..2208a95
--- /dev/null
+++ b/src/apply/partial.xsl
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/transform/apply-gen.xsl b/src/transform/apply-gen.xsl
index 2f7f032..1591d50 100644
--- a/src/transform/apply-gen.xsl
+++ b/src/transform/apply-gen.xsl
@@ -18,6 +18,13 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
+
+ TODOs:
+ - Properly handle arity overloading.
+ - Generate functions for partial applications, so long as the target
+ function does not have its arity overloaded (since that would
+ cause currying and partial application of N>1 arguments to
+ potentially yield different results).
-->
-
-
-
+
+
+
-
+
+
+
+
+
+
+
-
+
+
-
+
-
+
+
-
+
-
+
+
-
+
-
+
+
-
+
-
+
+
-
+
@@ -88,12 +115,15 @@
-
+
+
-
+
@@ -102,12 +132,15 @@
-
+
+
-
+
@@ -117,7 +150,24 @@
-
+
+
+
+
+
+
+
+
+
+
diff --git a/test/apply.xspec b/test/apply.xspec
index 8608775..7f6ad61 100644
--- a/test/apply.xspec
+++ b/test/apply.xspec
@@ -26,209 +26,554 @@
xmlns:foo="http://www.lovullo.com/_junk"
stylesheet="apply-test.xsl">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
-
+
+
-
-
-
-
+
+
+ test="$x:result[ 1 ] = foo:applied[ @n = 1 ]
+ and $x:result[ 2 ] is $args/foo:arg1" />
-
-
-
-
-
+
+
+
+ test="$x:result[ 1 ] = foo:applied[ @n = 2 ]
+ and $x:result[ 2 ] is $args/foo:arg1
+ and $x:result[ 3 ] is $args/foo:arg2" />
-
-
-
-
-
-
+
+
+
+
+ test="$x:result[ 1 ] = foo:applied[ @n = 3 ]
+ and $x:result[ 2 ] is $args/foo:arg1
+ and $x:result[ 3 ] is $args/foo:arg2
+ and $x:result[ 4 ] is $args/foo:arg3" />
-
-
-
-
-
-
-
+
+
+
+
+
+ test="$x:result[ 1 ] = foo:applied[ @n = 4 ]
+ and $x:result[ 2 ] is $args/foo:arg1
+ and $x:result[ 3 ] is $args/foo:arg2
+ and $x:result[ 4 ] is $args/foo:arg3
+ and $x:result[ 5 ] is $args/foo:arg4" />
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ test="$x:result[ 1 ] = foo:applied[ @n = 5 ]
+ and $x:result[ 2 ] is $args/foo:arg1
+ and $x:result[ 3 ] is $args/foo:arg2
+ and $x:result[ 4 ] is $args/foo:arg3
+ and $x:result[ 5 ] is $args/foo:arg4
+ and $x:result[ 6 ] is $args/foo:arg5" />
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ test="$x:result[ 1 ] = foo:applied[ @n = 6 ]
+ and $x:result[ 2 ] is $args/foo:arg1
+ and $x:result[ 3 ] is $args/foo:arg2
+ and $x:result[ 4 ] is $args/foo:arg3
+ and $x:result[ 5 ] is $args/foo:arg4
+ and $x:result[ 6 ] is $args/foo:arg5
+ and $x:result[ 7 ] is $args/foo:arg6" />
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ test="$x:result[ 1 ] = foo:applied[ @n = 7 ]
+ and $x:result[ 2 ] is $args/foo:arg1
+ and $x:result[ 3 ] is $args/foo:arg2
+ and $x:result[ 4 ] is $args/foo:arg3
+ and $x:result[ 5 ] is $args/foo:arg4
+ and $x:result[ 6 ] is $args/foo:arg5
+ and $x:result[ 7 ] is $args/foo:arg6
+ and $x:result[ 8 ] is $args/foo:arg7" />
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ test="$x:result[ 1 ] = foo:applied[ @n = 8 ]
+ and $x:result[ 2 ] is $args/foo:arg1
+ and $x:result[ 3 ] is $args/foo:arg2
+ and $x:result[ 4 ] is $args/foo:arg3
+ and $x:result[ 5 ] is $args/foo:arg4
+ and $x:result[ 6 ] is $args/foo:arg5
+ and $x:result[ 7 ] is $args/foo:arg6
+ and $x:result[ 8 ] is $args/foo:arg7
+ and $x:result[ 9 ] is $args/foo:arg8" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+ select="f:make-ref( QName( $foo-uri, 'fn1' ),
+ 1 )" />
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/apply/arity.xspec b/test/apply/arity.xspec
new file mode 100644
index 0000000..bb94b01
--- /dev/null
+++ b/test/apply/arity.xspec
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/apply/partial-test.xsl b/test/apply/partial-test.xsl
new file mode 100644
index 0000000..99dfadd
--- /dev/null
+++ b/test/apply/partial-test.xsl
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/apply/partial.xspec b/test/apply/partial.xspec
new file mode 100644
index 0000000..eda5a53
--- /dev/null
+++ b/test/apply/partial.xspec
@@ -0,0 +1,471 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/transform/apply-gen.xspec b/test/transform/apply-gen.xspec
index df9dae9..51de570 100644
--- a/test/transform/apply-gen.xspec
+++ b/test/transform/apply-gen.xspec
@@ -73,7 +73,7 @@
- "
+
@@ -187,7 +187,7 @@
- "
+
diff --git a/tools/xspec b/tools/xspec
index 3dc0ab2..20c6b8a 160000
--- a/tools/xspec
+++ b/tools/xspec
@@ -1 +1 @@
-Subproject commit 3dc0ab2e1b78dae5d31c228c22a7dd8868d5678f
+Subproject commit 20c6b8a32f37a6511698fe89b78b82fd1aa64bd2