|
[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Re: XPath 2.0: Problems with the two boolean const
> >
> > This is the bit that I don't understand. You must know something
> > about the values produced by the code you are calling, otherwise the
> > result is meaningless to the caller. What isn't clear to me (though
> > Jeni seems to have divined it in her usual way...) is what kind of
> > contract you want to have between the calling code and the called
> > code. Usually this contract is expressed in terms of types; if you
> > want to express it some other way, then I would like to understand
> > that.
>
> As I think you know, many of the generic templates that Dimitre uses
> in FXSL have "functions" as parameters. For example, the "map"
> function takes a sequence and a function as parameters, and returns
> the sequence constructed by applying the function on each of the items
> in the sequence.
>
> In these templates, you don't need to know what the function actually
> *does*, and therefore don't need to know what types of parameters it
> expects (as long as you know *how many* parameters it expects, I
> think).
>
> For example, you could imagine a kind of 'join' function that takes
> two sequences plus a two-argument function and returns a single
> sequence that is the result of applying the function on each pair of
> values from the two sequences. This would work with the 'and' function
> (which expects two booleans) or a 'plus' function (which expects two
> numbers).
>
> If you call the 'join' function directly, you know statically that the
> two sequences have to be booleans (or numbers) and that the result is
> a sequence of booleans (or numbers), based on the function that you
> pass to the 'join' function. So as a programmer using the function of
> course you know what it does. However, the implementation of the
> 'join' function is completely generic and it can't tell the types of
> the arguments or result of the function that it's passed (since we
> don't have reflection).
Wow... Jeni, what an excellent explanation!
Mike, here's an actual example from my latest work on FXSL for XSLT2:
func-apply.xsl:
==========
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f"
>
<xsl:function name="f:apply">
<xsl:param name="pFunc" as="element()"/>
<xsl:param name="arg1"/>
<xsl:apply-templates select="$pFunc">
<xsl:with-param name="arg1" select="$arg1"/>
</xsl:apply-templates>
</xsl:function>
<xsl:function name="f:apply">
<xsl:param name="pFunc" as="element()"/>
<xsl:param name="arg1"/>
<xsl:param name="arg2"/>
<xsl:apply-templates select="$pFunc">
<xsl:with-param name="arg1" select="$arg1"/>
<xsl:with-param name="arg2" select="$arg2"/>
</xsl:apply-templates>
</xsl:function>
<!-- The rest -- definitions of f:apply up to having 10 arguments
ommitted -->
</xsl:stylesheet>
func-foldl.xsl:
==========
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f"
>
<xsl:import href="func-apply.xsl"/>
<xsl:function name="f:foldl">
<xsl:param name="pFunc" as="element()"/>
<xsl:param name="pA0"/>
<xsl:param name="pList" as="item()*"/>
<xsl:sequence select=
"if (empty($pList))
then
$pA0
else
f:foldl($pFunc,
f:apply($pFunc, $pA0, $pList[1]),
$pList[position() > 1]
)"/>
</xsl:function>
</xsl:stylesheet>
testFunc-Foldl.xsl:
=============
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:foldl-func="foldl-func"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f foldl-func"
>
<xsl:import href="func-foldl.xsl"/>
<!-- This transformation must be applied to:
numList.xml
-->
<foldl-func:foldl-func/>
<xsl:variable name="vFoldlFun" select="document('')/*/foldl-func:*[1]"/>
<xsl:output encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:value-of select="f:foldl($vFoldlFun, 1, 1 to 10 )"/>
</xsl:template>
<xsl:template match="*[namespace-uri() = 'foldl-func']">
<xsl:param name="arg1" select="0"/>
<xsl:param name="arg2" select="0"/>
<xsl:value-of select="$arg1 * $arg2"/>
</xsl:template>
</xsl:stylesheet>
As we see, the function f:foldl() is a higher-order function, which is
passed a reference to a template and applies it to two arguments.
What is only known, id that the template passed as parameter accepts these
two parameters in the specified order and produces a result, which will
later be used in the recursive chain of operations.
The last stylesheet is an example of using f:foldl() to calculate the
product of the items of a sequence of numbers. The one that follows uses
f:foldl to say if all of the items of a sequence are true. To do this, we
just specify other parameters to f:foldl -- a template that performs a
logical and and an initial value of true (or 1):
func-allTrue.xsl:
===========
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fxl="http://fxsl.sf.net/"
xmlns:allTrue-And="allTrue-And"
exclude-result-prefixes="fxl xs allTrue-And"
>
<xsl:import href="func-foldl.xsl"/>
<allTrue-And:allTrue-And/>
<xsl:function name="fxl:allTrue" as="xs:boolean" >
<xsl:param name="pList" as="xs:boolean*"/>
<xsl:variable name="vAnd" select="document('')/*/allTrue-And:*[1]"/>
<xsl:copy-of select="fxl:foldl($vAnd, 1, $pList)"/>
</xsl:function>
<xsl:template name="And" match="*[namespace-uri()='allTrue-And']">
<xsl:param name="arg1"/>
<xsl:param name="arg2"/>
<xsl:value-of select="xs:boolean($arg1) and xs:boolean($arg2)"/>
</xsl:template>
</xsl:stylesheet>
this can further be used as a base for more complex functions, etc.
So which is the best way to specify (or not specify) parameter and
return-value type information for the template, passed as parameter to
f:apply()?
=====
Cheers,
Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|

Cart








