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

Editorial: optional position argument in function signature for for-each and other HOF #1514

Open
fsteimke opened this issue Oct 19, 2024 · 2 comments
Labels
Discussion A discussion on a general topic. XQFO An issue related to Functions and Operators

Comments

@fsteimke
Copy link

The change in 4.0 for the higher order function for-each is that "the $action callback function accepts an optional position argument". But the function signature is

fn:for-each(
  $input as item()*, 	
  $action as fn(item(), xs:integer) as item()* 	
) as item()*

I read $action as fn(item(), xs:integer) as item()* as a function with two mandatory parameters item() and xs:integer. Since the second (position) argument should be optional, i would expect:

fn:for-each(
  $input as item()*, 	
  $action as fn(item(), xs:integer?) as item()* 	
) as item()*

There are several HOFs with this new optional position argument which seems to be mandatory in the function signature.

@ChristianGruen
Copy link
Contributor

Closely related: #981.

This is due to the updated function coercion rules, which say:

If F has lower arity than T, then F is wrapped in a new function that declares and ignores the additional argument […].

In general, all parameters are now optional for this and all other callback findings; you can also supply true#0 as action argument.

JavaScript has chosen a similar approach (an example: forEach).

@ChristianGruen ChristianGruen added XQFO An issue related to Functions and Operators Discussion A discussion on a general topic. labels Oct 19, 2024
@michaelhkay
Copy link
Contributor

michaelhkay commented Oct 20, 2024

In response to a number of issues including #981, #1136, and #1175 I'm leaning towards:

  1. Allowing parameter names in function signatures, initially with no meaning attached to them: function($item as item()*, $position as xs:integer) as xs:boolean is an alternative designation of the type function(item(), xs:integer) as xs:boolean.
  2. Marking optional parameters in a function signature. Perhaps with a ? after the name, so function($item as item(), $position? as xs:integer) as xs:boolean indicates that the $position argument is optional. If any argument is optional then all subsequent arguments must be optional. Or perhaps with the syntax function($item as item(), $position as xs:integer := ?); though the similarity of syntax to optional parameters in function declarations hides a significant difference in semantics.
  3. Dropping the "arity increasing" function coercion, and replacing it with changes to the type matching rules. Specifically, a function declared as fn($i as item()) as xs:boolean {true()} matches the type fn($item as item(), $pos? as xs:integer) as xs:boolean. As a consequence, both types fn($a) and fn($a, $b) are subtypes of fn($a, $b?).
  4. Allowing parameters of a function item to be optional, using the syntax function($item as item(), $pos as xs:integer := -1) {...} to indicate the fact
  5. Changing the rules on dynamic function calls so that optional parameters can be omitted.

This is of course just a sketch, there is a lot of detail to be worked out. But it feels feasible.

The one thing I haven't included is allowing argument keywords in dynamic function calls. That's tricky because we don't want to disallow supplying a callback function that happens to use different parameter names. However, it might be possible to solve that if function coercion performs a remapping of parameter names.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Discussion A discussion on a general topic. XQFO An issue related to Functions and Operators
Projects
None yet
Development

No branches or pull requests

3 participants