- From: Tim Mills <tim@cbcl.co.uk>
- Date: Tue, 10 May 2016 11:33:34 +0100
- To: public-xsl-query@w3.org

(: ACTION A-642-06 on Bug 29586 Recall that function coercion occurs to convert an argument value or a return value to its expected TypedFunctionTest type. Function coercion wraps a function in a new function with signature the same as the expected type. This function has the same name as the function it wraps. The specification notes that static typing will often be able to reduce the number of places where this is actually necessary. However, FunctionTest matching is described in terms of checking its function signature and annotations. This means that the static type of a function item is entirely dependent on its signature and annotations, and not on, for example, the static type of the function body. For example, while function() as xs:integer { 1 } instance of function() as xs:integer is true. function() { 1 } instance of function() as xs:integer is false. For comparison, it is implementation defined whether or not (1.2 + 0.8) instance of xs:integer is true. This has the consequence that an implementation may be forced to perform unnecessary function coercion. :) (: The following function declarations differ only in their names and signatures. The function bodies are identical. :) declare function local:items-to-items($arg) { xs:long( typeswitch ($arg) case xs:long return 1 case xs:integer return 2 default return 3) }; declare function local:anyAtomic-to-items($arg) { xs:long( typeswitch ($arg) case xs:long return 1 case xs:integer return 2 default return 3) }; declare function local:items-to-integer($arg) as xs:integer { xs:long( typeswitch ($arg) case xs:long return 1 case xs:integer return 2 default return 3) }; declare function local:integer-to-items($arg as xs:integer) { xs:long( typeswitch ($arg) case xs:long return 1 case xs:integer return 2 default return 3) }; declare function local:integer-to-integer($arg as xs:integer) as xs:integer { xs:long( typeswitch ($arg) case xs:long return 1 case xs:integer return 2 default return 3) }; declare function local:integer-to-long($arg as xs:integer) as xs:long { xs:long( typeswitch ($arg) case xs:long return 1 case xs:integer return 2 default return 3) }; declare function local:invoke($arg as function(xs:integer) as xs:integer) as xs:integer { $arg(1) }; ( (: Case 1: local:integer-to-integer#1 is exactly the expected type * return type xs:integer is exactly the expected xs:integer * expected xs:integer is exactly the argument type xs:integer Function coercion can be eliminated. :) local:invoke(local:integer-to-integer#1), (: Case 2: local:integer-to-long#1, more specific return type * return type xs:long is subtype of expected xs:integer * expected xs:integer is exactly the argument type xs:integer Function coercion can be eliminated. :) local:invoke(local:integer-to-long#1), (: Case 3: local:items-to-integer#1, less specific argument type * return type xs:integer is exactly the expected xs:integer * expected xs:integer is a subtype of argument type item()* Function coercion can be eliminated. :) local:invoke(local:items-to-integer#1), (: Case 4: local:integer-to-items#1, less specific return type * return type item()* is NOT a subtype of expected xs:integer * expected xs:integer is exactly the argument type xs:integer Function coercion cannot (currently) be eliminated. :) local:invoke(local:integer-to-items#1), (: Case 5: local:anyAtomic-to-items#1, less specific return type * return type item()* is NOT a subtype of expected xs:integer * expected xs:integer is a subtype of the argument type xs:anyAtomicType Function coercion cannot (currently) be eliminated. :) local:invoke(local:integer-to-items#1), (: Case 6: local:items-to-items#1, less speific argument and return type. * return type item()* is NOT a subtype of expected xs:integer * expected xs:integer is a subtype of argument type item()* Function coercion cannot (currently) be eliminated. :) local:invoke(local:items-to-items#1), (: Case 7: [2, 2, 2] matches function(xs:integer) as item()*, (like Case 4) * return type item()* is NOT a subtype of expected xs:integer * expected xs:integer is exactly the argument type xs:integer Function coercion cannot (currently) be eliminated. Propose that array(V) should match function(xs:integer) as V. :) local:invoke([2, 2, 2]), (: Case 8: map { 1 : 2, 2 : 2} matches function(xs:anyAtomicType) as item()*. (like Case 5) * return type item()* is NOT a subtype of expected xs:integer * expected xs:integer is a subtype of the argument type xs:anyAtomicType Function coercion cannot (currently) be eliminated. Propose that map(K, V) should match function(xs:anyAtomicType) as V. :) local:invoke(map { 1 : 2, 2 : 2 } ) )

Received on Tuesday, 10 May 2016 10:34:06 UTC