Subject: [xsl] Re: Re: XPath 2.0: Problems with the two boolean constants true and false From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx> Date: Thu, 9 Oct 2003 20:09:49 +0200 |
> > > > 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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Re: XPath 2.0: Problems w, Jeni Tennison | Thread | RE: [xsl] Re: XPath 2.0: Problems w, Dimitre Novatchev |
Re: [xsl] How to add a string to an, Mukul Gandhi | Date | Re: [xsl] Selecting the xsl-file, J.Pietschmann |
Month |