This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 24511 - Function item and maps, error situations or side effects
Summary: Function item and maps, error situations or side effects
Status: CLOSED INVALID
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Last Call drafts
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Michael Kay
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-02-05 04:27 UTC by Abel Braaksma
Modified: 2014-02-24 15:05 UTC (History)
2 users (show)

See Also:


Attachments

Description Abel Braaksma 2014-02-05 04:27:12 UTC
Given that a function with a signature function(xs:anyAtomicType) as item()* matches any map, should we say anything about assigning functions to items that are declared as maps?

I mean, one could assign concat#1 to a map, which wouldn't do much other than return the key as the value. But what happens if a function returns an error, i.e., error#1 (or is the "none" type of fn:error not compatible with item()*?). But any other function can return an error.

And what happens when functions have side effects, like creating a new node or a constructor function, or a function calling xsl:stream? 

Perhaps the behavior should be implementation defined, similarly to xsl:variable (which can be evaluated again and again, but can also be cached).
Comment 1 Innovimax 2014-02-05 08:16:19 UTC
I think you ask many question at once here ?

I don't see any problem having a function as a value of the map, you'll need to apply it to something to have an error.
Comment 2 Michael Kay 2014-02-05 12:07:18 UTC
>Given that a function with a signature function(xs:anyAtomicType) as item()* matches any map

It's not clear what you are saying here.

It's true that where the required type is function(xs:anyAtomicType) as item()*, you can supply a map.

It's not true that where the required type is map(*), you can supply any instance of function(xs:anyAtomicType) as item()*.

>I mean, one could assign concat#1 to a map

No, if the required type is map(*), then you can't pass concat#1 as the value.
Comment 3 Abel Braaksma 2014-02-05 17:04:00 UTC
Maybe I misunderstand maps, but I thought the following is possible:

<xsl:variable name="m" as="map(xs:string, xs:boolean)" select="lang#1" />
<xsl:value-of select="map:keys($m)" />

Reason why I think it is possible is that the type of lang#1 is function(xs:string?) as xs:boolean. Testing it with our own processor and with Saxon gives an error that the types are not compatible, perhaps because of the cardinality of the argument of fn:lang.

Similarly, I would say that the following holds:

<xsl:function name="f:test" as="item()*">
    <xsl:param name="a" as="xs:anyAtomicType" />
    <xsl:value-of select="'test'" />
</xsl:function>

<xsl:variable name="m" as="map(xs:anyAtomicType, item()*)" select="f:test#1" />
<xsl:value-of select="map:keys($m)" />

But again, both Exselt and Saxon raise (probably correctly?) an error here. Reading up in the spec I find the following:

"The function signature of the map, treated as a function, is always function(xs:anyAtomicType) as item()*, regardless of the actual types of the keys and values in the map."

If that is true, even if the type of map is specified, then it is understandable why the first example above doesn't hold (return type is covariant). But the second example seems compatible with the function type in the sense that:

map(xs:anyAtomicType, item()*) instance of function(xs:anyAtomicType) as item()*

and:

function(xs:anyAtomicType) as item()* instance of map(xs:anyAtomicType, item()*) 

More precisely, the spec says a lot about using the function coercion rules from map to function, but leaves out the coercion from function to map. In the subtype relationships this is not mentioned (under 21.1.1, last paragraph), but perhaps (and that is a misunderstanding from my end), on purpose: it only shows that function(*) and function(xs:anyAtomicType) as item()* are subtypes of map(*).

@Innovimax: I didn't mean a function as a value of a map, but a function item as a map.
Comment 4 Innovimax 2014-02-05 18:11:06 UTC
Yes, I wasn't high enough! Sorry for disrupting.

But interesting question by all means!!
Comment 5 C. M. Sperberg-McQueen 2014-02-11 15:53:58 UTC
We discussed this in Prague; it was raised under a misapprehension concerning the relations of maps and functions owing to the error described in bug 24456.  No action needed.