Re: Proposal for variadic functions

At a first glance I like this summary of the proposals that were made so
far.
What I and Liam have been proposing is essentially what is described here
as: "B. Bounded-variadic functions".



On Tue, Dec 8, 2020 at 12:57 AM Michael Kay <mike@saxonica.com> wrote:

> ...
>



> If a function is variadic, then its name must be unique within the static
> context.
>

Does this mean that there cannot exist two variadic functions with the same
name, for example

    myFun($arg1, $arg2, $arg3 default: 0 )

and

      myFun($argName1, $argName2 default: 3 )

If so, why is this restriction?


> A variadic function can be identified by a function reference of the form
> name#*. fn:function-arity applied to a variadic function returns ();
> fn:function-lookup and fn:function-available accept a second argument of ()
> to identify a variadic function.
>


I think it would be more precise to have: name#m-n  where m is the number
of positional/required arguments and n is the number of keyword arguments.
(It could be: (total-number-of-arguments, number-of-keyword-arguments) or
similar variations). If we want to have unbounded number of keyword
arguments, then this would be specified as name#m-*  .

The arity of any function is now a sequence of one or two integers, where
the first integer is the number of positional arguments and the second, if
present, is the number of keyword arguments. This will not break existing
code that looks up for functions having arity that is just one number (a
sequence of one number).



> A function call contains zero or more positional arguments followed by
> zero or more keyword arguments. Keyword arguments can also be used when
> calling non-variadic functions, though the number of arguments in that case
> is fixed.
>
> We identify three kinds of variadic function, which I will call
> bounded-variadic, array-variadic, and map-variadic.
>
> B. Bounded-variadic functions.
>
> In a bounded-variadic function, one or more of the parameters are declared
> as optional, with a default value.
>
> The number of supplied arguments in a function call must be >= the number
> of non-optional parameters, and <= the total number of declared parameters.
> (Hence the name, bounded).
>
> A positional argument is bound to the parameter at the corresponding
> position. A keyword argument is bound to the parameter with the
> corresponding name. It is an error if two arguments are bound to the same
> parameter, or if no argument is bound to a required parameter, or if too
> few or too many arguments are supplied.
>
> 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.
>
> Typical example: format-date(). This can now be redefined as a
> bounded-variadic function with 5 declared parameters of which the last
> three are optional. Calls with two positional arguments and five positional
> arguments remain valid; it also becomes possible to supply 3 or 4
> positional arguments, and to supply any of the arguments (including the
> required arguments) using keywords.
>
> 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.
>

As other people asked, I don't understand what "virtual fixed-arity"
function means. Please, elaborate and provide an example.


>
> 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 [].
>
> The number of supplied arguments must be >= the number of required
> parameters (where the array argument is not counted as a required
> parameter: it effectively defaults to an empty array). There is no upper
> bound on the number of arguments.
>
> Typical example: concat(). All existing calls of concat remain valid, as
> do function references such as concat#17. But it now becomes possible to
> supply a single argument as an array, by keyword.
>
> D. Map-variadic functions.
>
> In a map-variadic function, the last parameter has a map type. All keyword
> arguments in the function call are combined into a map, which is supplied
> as the value of this last parameter. Values for parameters other than the
> last can only be supplied positionally. It is also possible for the
> function call to supply the map as a single argument, in which case it must
> be supplied as a positional argument. The map has an implicit default of
> map{}.
>
> The number of supplied arguments must be >= the number of required
> parameters (where the map argument is not counted as a required parameter:
> it effectively defaults to an empty map). There is no upper bound on the
> number of arguments.
>
> Typical example: serialize(). You can supply any keywords you like; the
> function will ignore any that it doesn't recognise.
>

Because in a function call we can reference now any argument by name (even
a positional argument), we must specify a restriction that the (names of
the) keys of the map do not clash with the names of the positional
arguments, or to allow in this case a mechanism for disambiguation,
something like:

myName: 5  (: for positional argument :)

and

?myName: 12 (: for keyword argument :)



Thanks,
Dimitre



On Tue, Dec 8, 2020 at 12:57 AM Michael Kay <mike@saxonica.com> wrote:

> Here is an attempt to consolidate a proposal for variadic functions that
> combines all the ideas and requirements that have been expressed.
>
> I would worry that the proposal is over-complex, if it weren't that Python
> seems to offer all these options and users seem quite happy with it.
>
> Note: I use the word parameters to refer to things in the function
> declaration, and arguments to refer to things in the function call. The
> distinction is important.
>
> TODO: I haven't tried yet to define rules for partial application.
>
> A. Some general rules about variadic functions.
>
> If a function is variadic, then the number of arguments in a function call
> can differ from the number of parameters in the function declaration.
>
> If a function is variadic, then its name must be unique within the static
> context.
>
> A variadic function can be identified by a function reference of the form
> name#*. fn:function-arity applied to a variadic function returns ();
> fn:function-lookup and fn:function-available accept a second argument of ()
> to identify a variadic function.
>
> A function call contains zero or more positional arguments followed by
> zero or more keyword arguments. Keyword arguments can also be used when
> calling non-variadic functions, though the number of arguments in that case
> is fixed.
>
> We identify three kinds of variadic function, which I will call
> bounded-variadic, array-variadic, and map-variadic.
>
> B. Bounded-variadic functions.
>
> In a bounded-variadic function, one or more of the parameters are declared
> as optional, with a default value.
>
> The number of supplied arguments in a function call must be >= the number
> of non-optional parameters, and <= the total number of declared parameters.
> (Hence the name, bounded).
>
> A positional argument is bound to the parameter at the corresponding
> position. A keyword argument is bound to the parameter with the
> corresponding name. It is an error if two arguments are bound to the same
> parameter, or if no argument is bound to a required parameter, or if too
> few or too many arguments are supplied.
>
> 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.
>
> Typical example: format-date(). This can now be redefined as a
> bounded-variadic function with 5 declared parameters of which the last
> three are optional. Calls with two positional arguments and five positional
> arguments remain valid; it also becomes possible to supply 3 or 4
> positional arguments, and to supply any of the arguments (including the
> required arguments) using keywords.
>
> 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.
>
> 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 [].
>
> The number of supplied arguments must be >= the number of required
> parameters (where the array argument is not counted as a required
> parameter: it effectively defaults to an empty array). There is no upper
> bound on the number of arguments.
>
> Typical example: concat(). All existing calls of concat remain valid, as
> do function references such as concat#17. But it now becomes possible to
> supply a single argument as an array, by keyword.
>
> D. Map-variadic functions.
>
> In a map-variadic function, the last parameter has a map type. All keyword
> arguments in the function call are combined into a map, which is supplied
> as the value of this last parameter. Values for parameters other than the
> last can only be supplied positionally. It is also possible for the
> function call to supply the map as a single argument, in which case it must
> be supplied as a positional argument. The map has an implicit default of
> map{}.
>
> The number of supplied arguments must be >= the number of required
> parameters (where the map argument is not counted as a required parameter:
> it effectively defaults to an empty map). There is no upper bound on the
> number of arguments.
>
> Typical example: serialize(). You can supply any keywords you like; the
> function will ignore any that it doesn't recognise.
>
> Michael Kay
> Saxonica
>


-- 
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
Never fight an inanimate object
-------------------------------------
To avoid situations in which you might make mistakes may be the
biggest mistake of all
------------------------------------
Quality means doing it right when no one is looking.
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play
-------------------------------------
To achieve the impossible dream, try going to sleep.
-------------------------------------
Facts do not cease to exist because they are ignored.
-------------------------------------
Typing monkeys will write all Shakespeare's works in 200yrs.Will they write
all patents, too? :)
-------------------------------------
Sanity is madness put to good use.
-------------------------------------
I finally figured out the only reason to be alive is to enjoy it.

Received on Tuesday, 8 December 2020 16:00:33 UTC