Re: Proposal for variadic functions

> On 8 Dec 2020, at 10:05, Norm Tovey-Walsh <norm@saxonica.com> wrote:
> 
> Michael Kay <mike@saxonica.com> writes:
>> TODO: define the rules for evaluation of default values, e.g. can they
>> be context dependent (if so, what is the context), can the default
>> value of one argument depend on the supplied values of other
>> arguments, etc.
> 
> I can see how the context would be useful, though it seems quite
> complicated. Allowing one argument to depend on the supplied values of
> other arguments seems odd. You mentioned Python at the beginning of your
> message, does Python allow this in some form?

I don't know, needs research. FWIW, the context rules for evaluating default parameter values in xsl:param have never been 100% clear. The simplest approach is to make the context minimal, but you have to allow things like xs:date, and it seems reasonable to allow current-date() as a default. It would be nice to allow user-written functions to do anything that system-defined functions can do, e.g. defaulting an argument to the default collation from the static context of the caller, but defining that gets quite complicated. I'd prefer to avoid the complexities of allowing reference to local variables appearing in the context of the function declaration. Perhaps we shouldn't even allow non-global functions to be variadic.
> 
>> For compatibility, format-date#2 and format-date#5 remain available as
>> references to virtual fixed-arity functions that map directly to the
>> variadic function.
> 
> How does that work? Is this a special case for backwards compatibility,
> or is something else going on?

My thinking is it's needed for backwards compatibility, but it doesn't need to be special-cased. If a call to F(a, b, c, d) with four positional arguments would be legal then we can make F#4 return a "virtual" non-variadic function that performs that call.
> 
>> C. Array-variadic functions.
>> 
>> In an array-variadic function, the last parameter has an array type.
>> If the last parameter is at position N, then the supplied arguments at
>> position N, N+1. N+2, etc, are combined into an array, and the array
>> is passed as the value of the last parameter. The caller also has the
>> option of passing an actual array as the value of the argument; this
>> is done by using a keyword argument. The array has an implicit default
>> of [].
> 
> Just testing my understanding. Given
> 
>  function f($x as xs:integer, $y as array(xs:integer))
> 
> I could write:
> 
>  f(1) ===> f(1, array {})
>  f(1, 3, 4, 5) ==> f(1, array { (3,4,5) })
>  f(1, array { (3,4,5) }) ===> f(1, array { array { (3,4,5) }})
>  f(1, $y=array { (3,4,5) }) ===> f(1, array { (3,4,5) })
> 
> Is that right?

Yes; but the third call would be a type error, because you're supplying an array of arrays where an array of integers is required.

IIRC array{ (3,4,5) } is an array holding one member whose value is the sequence (3,4,5)? But I need to check. I think you meant the array [3,4,5].

The syntax $y=expr for keyword arguments won't parse unambiguously; I think the choice is between y: [3,4,5] and y := [3,4,5].)
> 
>> Typical example: serialize(). You can supply any keywords you like;
>> the function will ignore any that it doesn't recognise.
> 
> “Will ignore” is the same as, “they will be added to the map and passed
> to the function, but the function ignores map values it doesn’t
> recognize”, yes?
> 

The function can do anything it likes with the map, but that's what serialize() will choose to do.

Michael Kay
Saxonica

Received on Tuesday, 8 December 2020 10:22:14 UTC