Project

Profile

Help

Bug #5205

closed

Map → function argument

Added by Christian Grün about 2 years ago. Updated about 2 years ago.

Status:
Closed
Priority:
Low
Assignee:
Category:
-
Sprint/Milestone:
-
Start date:
2022-01-14
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
10
Fix Committed on Branch:
Fixed in Maintenance Release:
Platforms:

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()
Actions #1

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.

Actions #2

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)
Actions #3

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.

Actions #4

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.

Actions #5

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

Also available in: Atom PDF