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

Function Coercion: Function Arities #705

Closed
ChristianGruen opened this issue Sep 15, 2023 · 5 comments
Closed

Function Coercion: Function Arities #705

ChristianGruen opened this issue Sep 15, 2023 · 5 comments
Labels
Editorial Minor typos, wording clarifications, example fixes, etc. Propose Closing with No Action The WG should consider closing this issue with no action XPath An issue related to XPath

Comments

@ChristianGruen
Copy link
Contributor

ChristianGruen commented Sep 15, 2023

In 4.6.4 Function Coercion, a rule was added to support functions with an arity lower than the expected one:

If F has lower arity than the expected type, then F is wrapped in a new function that declares and ignores the additional argument; the following steps are then applied to this new function.

If I got it right, this is the resulting 4.0 behavior:

Spoiler: I probably got it wrong, see the next comment.

declare function local:function($a) { };
declare variable $function := function($a) { };

(: now legal :)
filter    (1984, true#0)
$function (1984, 'ignored')
fn { }    (1984, 'ignored')
map { }   (1984, 'ignored')
true#0    ('ignored')
sum(?, ())(1984, 'ignored')

(: still illegal :)
local:function(1984, 'ignored')

(: still legal: RHS items will be supplied one by one :)
map { }(1984, 'processed')     

Maybe some more examples should be added in the corresponding sections that refer to function coercion.

The new rule is powerful and allows for greater flexibility (see #516 and other issues), but the behavior may also be unexpected. We should probably document that:

  • It may go unnoticed that a passed on argument will be ignored. In other words, we reduce type safety by allowing users to supply more arguments than will be processed.
  • It makes a difference whether the invoked function is static or dynamic (dynamic functions will now provide less type safety than static functions).
@ChristianGruen ChristianGruen added XPath An issue related to XPath Editorial Minor typos, wording clarifications, example fixes, etc. Tests Needed Tests need to be written or merged labels Sep 15, 2023
@ChristianGruen
Copy link
Contributor Author

ChristianGruen commented Sep 16, 2023

I discovered FunctionCall-416, and I guess I got it wrong. I can partly answer my question by myself…

If let $f := concat#4 return $f('a', 'b', 'c', 'd', 'e') is supposed to raise an error,
why is filter(1984, function() { true() }) legal?

…as I see that 4.6.2.2 Evaluating Dynamic Function Calls is clear when it comes to the function arity:

  1. The function item F to be called is obtained by evaluating the base expression of the function call. If this yields a sequence consisting of a single function item whose arity matches the number of arguments in the ArgumentList, let F denote that function item. Otherwise, a type error is raised [err:XPTY0004].

Sorry for the noise, but I think some more examples would help, presenting cases in which the function coercion is actually applied, besides from built-in functions.

@michaelhkay
Copy link
Contributor

Coercion happens when you supply a value V for a variable or function argument requiring a type T. So if you supply a function of arity 1 where a function of arity 2 is required, coercion happens. It doesn't happen on the dynamic function call itself.

@ChristianGruen
Copy link
Contributor Author

Thanks for helping me think. – It took me longer than I hoped to formulate sensible examples, until I realized that the proposed extensions in #516 can simply be written as user-defined functions. Another example would be this:

let $upper-case-when := function(
  $string as xs:string,
  $test   as function(item()) as item()
) as xs:string {
  if ($test($string)) then upper-case($string) else $string
}
return $upper-case-when('always', true#0)

Maybe there are better examples, suggestions are welcome.

I can imagine it’s tricky to grasp though, so I’ll keep this issue open until we’ve added one or more examples in the text, for example to the existing note (“This mechanism makes it easier to design versatile and extensible higher-order functions. […]”).

@ChristianGruen ChristianGruen self-assigned this Sep 16, 2023
@ChristianGruen
Copy link
Contributor Author

I left this open because I thought that more examples would be helpful for the coercion rules.
We can discuss this again later if someone besides me thinks it would be constructive.

@ChristianGruen ChristianGruen added the Propose Closing with No Action The WG should consider closing this issue with no action label Dec 14, 2023
@ChristianGruen ChristianGruen removed their assignment Dec 18, 2023
@ndw
Copy link
Contributor

ndw commented Dec 19, 2023

The CG agreed to close this issue without action meeting 59.

@ndw ndw closed this as completed Dec 19, 2023
@ChristianGruen ChristianGruen removed the Tests Needed Tests need to be written or merged label Feb 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Editorial Minor typos, wording clarifications, example fixes, etc. Propose Closing with No Action The WG should consider closing this issue with no action XPath An issue related to XPath
Projects
None yet
Development

No branches or pull requests

3 participants