Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support named arguments on static function calls #159

Closed
rhdunn opened this issue Sep 27, 2022 · 5 comments
Closed

Support named arguments on static function calls #159

rhdunn opened this issue Sep 27, 2022 · 5 comments
Labels
Completed PR has been applied, tests written and tagged, no further action needed Feature A change that introduces a new feature XPath An issue related to XPath XQuery An issue related to XQuery XSLT An issue related to XSLT

Comments

@rhdunn
Copy link
Contributor

rhdunn commented Sep 27, 2022

This proposal adds the ability to specify the names (referred to here as "keywords") of the parameters of a function at the point at which the function is called. This uses the form name: value where name is a QName and value is a single expression, for example fn:tokenize("abcbdCef", pattern: "c", flags: "i").

Motivation

If a function takes several arguments of the same type (xs:boolean, xs:integer, xs:string, etc.) it can be easy to mix up the parameters. As such, it can be useful to specify these by name when calling the function, e.g. f(a: true(), b: false(), c: true()) to both aid readability and to prevent bugs when the values are specified in the wrong order to how they are declared (such as swapping the $pattern and $flags parameters in fn:tokenize).

If a function takes several optional parameters and the caller only wants to override one of the later parameters (such as the $collation in fn:differences), specifying the name of the parameter avoids specifying a value for the other arguments. This makes it clearer what is happening (as the user does not need to think about the supplied default arguments), and reduces errors (such as specifying a wrong default value for the arguments the caller is not interested in).

Notes

Because function parameter names are EQNames, the keyword should also be an EQName. If the keyword is an NCName, then it should follow the same rules as parameter NCNames such that the namespace URI is empty.

Like with maps, if the value starts with an element name (EQName) then there must be a space after the :. This should use the same note as the one in the map constructor section.

An alternative name := value syntax has also been suggested. An informal consensus is in favour of using name: value.

@rhdunn rhdunn added XPath An issue related to XPath Feature A change that introduces a new feature labels Sep 27, 2022
@rhdunn rhdunn changed the title Proposal to support named arguments on static function calls Proposal to support named arguments on static function calls. Sep 27, 2022
@michaelhkay
Copy link
Contributor

The use of keywords to identify function parameters in static function calls creates a problem in XSLT where a function defined in one package is overridden by a function in another package. The XSLT 3.0 rules do not require the overriding function to use the same parameter names.

This differs from named templates, where there is such a requirement, included in the spec on the basis that the caller needs to know the parameter names. For functions, by contrast, it was assumed that parameter names were of local significance only.

Several solutions come to mind, none of them especially attractive:

  • Allow keyword syntax in a function call only if it has been explicitly enabled for that function, in which case overriding functions must use the same parameter names.
  • Make the rules version-sensitive: essentially the same as the previous rule, where "explicitly enabled" means having an effective version >= 4.0.
  • Alternatively, use of keywords might be "explicitly enabled" by virtue of the fact that one or more parameters are declared optional.
  • Say that the parameter names in an overriding function are ignored (outwith the function body) and that the names exposed to callers are the names used in the function being overridden.
  • Break backwards compatibility: impose a retrospective rule that the names must match.
  • A combination of the above: add the rule that the names must match, but with a fallback recovery action if version<=4.0 that if the names in an overriding function don't match, they are effectively substituted with names that do match.

We also need to consider whether an overriding function should allow additional optional parameters to be declared that are not present on the overridden function, as we do for named templates. It's a bit trickier to achieve for functions because you can have multiple functions with the same name and different arity, and you might find yourself overriding a different function. In principle, one can imagine a single function declaration in a using package overriding several function declarations (with different arity) in the used package, or vice versa. We probably need a rule along the lines that the overridden package must contain exactly one function declaration whose arity range overlaps the arity range of the overriding function.

@michaelhkay
Copy link
Contributor

The pull request for issue #155 supports this feature.

@michaelhkay
Copy link
Contributor

In response to the comments on the PR, I propose to make the following changes.

  1. Revert the description of the default function namespace to the 3.1 description. This is otherwise a distraction.
  2. Throughout the language spec , refer to "dynamic functions" as "function items" rather than "functions" or "dynamic function". It's confusing to have three names for the same thing, and it's confusing to use the name "function" exclusively for function items to the exclusion of static functions. The term "dynamic function" is confusing because some function items may have a static presence (e.g. if bound to a static variable in XSLT).
  3. Rename the component of the static context called "statically-known function signatures" in 3.1, and "declared functions" in the current PR, as "statically-known function definitions".
  4. Rename the concept named "declared function" in the current PR as "function definition"; a function definition that is present in the static context (as distinct from one known only at run time) is a "static function definition".
  5. In the description of the static context, cut out the categorisation of static function definitions, or abbreviate it and move it into a note.
  6. In the dynamic context, rename "Named functions" as "dynamically-known function definitions", and recast it as a superset of the statically-known function definitions.
  7. Recast the intro to 4.4 Functions so we don't present static and dynamic functions as two different kinds of "function"; rather, present static function definitions and function items as distinct but related concepts.

@ChristianGruen
Copy link
Contributor

Just in case this hasn’t been dealt with yet: Do we also want to support named parameters for type constructor functions? The current parameter name is arg; we could rename it to $value or $input.

@ChristianGruen ChristianGruen changed the title Proposal to support named arguments on static function calls. Support named arguments on static function calls Apr 27, 2023
@michaelhkay
Copy link
Contributor

We accepted this feature a while ago and the issue should have been closed.

@michaelhkay michaelhkay added XQuery An issue related to XQuery XSLT An issue related to XSLT Completed PR has been applied, tests written and tagged, no further action needed labels Apr 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Completed PR has been applied, tests written and tagged, no further action needed Feature A change that introduces a new feature XPath An issue related to XPath XQuery An issue related to XQuery XSLT An issue related to XSLT
Projects
None yet
Development

No branches or pull requests

3 participants