Bug #5205
closedMap → function argument
0%
Description
Triggered by a Slack comment (https://app.slack.com/client/T011VK9115Z/C011NLXE4DU/thread/C011NLXE4DU-1641484160.002700):
The following expression returns 1:
declare function local:f($f as function(item()?) as item()) {
1
};
local:f(map { })
I would have expected XPTY0004, as a map is no instance of function(item()?) as item()
, and as the following expression yields an error:
map { } treat as
function(item()?) as item()
Updated by Michael Kay about 2 years ago
I guess (without examining it in detail) that function inlining is probably removing the type check on the unused argument?
That's permitted under the infamous "errors and optimization" rules. I don't like relying on those rules, but sometimes we have to.
Updated by Christian Grün about 2 years ago
I’ve tried a recursive variant of the function, it seems to work as well:
declare function local:f(
$f as function(item()?) as item(),
$i as xs:integer
) {
if ($i > 0) then local:f($f, $i - 1) else 1
};
local:f(map { }, 1000)
Updated by Michael Kay about 2 years ago
I think that while an empty map is not an instance of function(item()?) as item()
, function coercion allows it to be coerced to that type which means it can be supplied as the actual value of an argument whose expected type is function(item()?) as item()
.
XPath 3.1 §2.5.5.8 discusses this: "In such cases, a type error will only occur if an actual call on the map (treated as a function) returns a value that is not an instance of the required return type." In both these examples, there is no actual call on the map (treated as a function), so there is no type error.
The spec issue https://github.com/w3c/qtspecs/issues/14 is relevant here. If we accept Abel's suggestion to take the definitive text from F+O §17.1, namely
The function corresponding to the map has the signature
function($key as xs:anyAtomicValue) as item()*
**
then the question is, can you supply an instance of function($key as xs:anyAtomicValue) as item()*
where the expected type is function(item()?) as item()
,
I think the rules of XPath §3.1.5.3 (function coercion) make it clear that you can, and that no error occurs unless the function is actually invoked and returns a sequence that doesn't match the return type item()
.
I propose to close this with no action, but happy to continue the discussion if you think this analysis is wrong.
Updated by Christian Grün about 2 years ago
Thanks for the pointer to https://github.com/w3c/qtspecs/issues/14. I remembered there was a related discussion, but I couldn’t recollect where it was discussed.
Feel free to close the issue.
Updated by Michael Kay about 2 years ago
- Status changed from New to Closed
- Assignee set to Michael Kay
Closed with no action
Please register to edit this issue