Re: xsl:function with optional parameters

It would probably be best to review the proposal as a whole, which I have now committed, rather than my musings on how to handle this particular edge case. But I'll address the questions.

> 
> First, I have what seems like a logically prior question.  If a
> stylesheet has something like the following
> 
>    <xsl:function name="my:f" as="...">
>       <xsl:param name="p1" as="node()"/>
>       <xsl:param name="p2" as="xs:integer" required="no" select="42"/>
>       ...
>    </
> 
> then how many functions is it declaring?
> 
> It seems to me the spec can answer in at least two possible ways,
> formally speaking:
> 
>   (a) It is a declaration of a function (one function) which has one
>   required and one optional parameter, which can therefore be called
>   with either one or two arguments.
> 
>   (b) It is a declaration of two (related) functions, one of which is
>   my:f#1 and the other of which is my:f#2.  The xsl:function element in
>   question is in effect shorthand for 
> 
>    <!-- my:f#1 (just calls my:f#2 with the default value for p2) -->
>    <xsl:function name="my:f" as="...">
>       <xsl:param name="p1" as="node()"/>
>       <xsl:sequence select="my:f($p1, 42)"/>
>    </
> 
>    <!-- my:f#2 -->
>    <xsl:function name="my:f" as="...">
>       <xsl:param name="p1" as="node()"/>
>       <xsl:param name="p2" as="xs:integer"/>
>       ...
>    </
> 
>    I'll call the collection of functions thus declared a 'function
>    family'.
> 
> I think your notes are assuming (a), which is perfectly reasonable.  But
> I wonder if (b) might be worth thinking about.  It would have the
> advantage that it would require not change (that I can see, at the
> moment) to the type system as it relates to functions.  At least, that
> looks like an advantage to me.

In earlier drafts I used design (b), and I have switched to (a). The reason for this is concerned with binding of static function calls using keywords. If we only allowed positional calls with either one or two arguments, then it would work perfectly well to have two separate functions with different arities, chosen according to the arity of the function call. If however we have a function with two optional parameters p1 and p2, allowing calls to take six different forms:

f()
f(p1:=x)
f(p2:=y)
f(p1:=x, p2:=y)
f(x)
f(x,y)

then it becomes somewhat tortuous to argue that there are three functions here, and to work out which of the three functions is called by each of these 6 calls.

Another point in favour of (a) is the handling of dynamic context in parameter defaults. If we want to allow a default of "." (meaning the context item of the caller), then we can't say that there is an implicit function

function f() {
  f(.)
}

because "." is not available within the function body.

Michael Kay
Saxonica

Received on Friday, 30 September 2022 07:17:46 UTC