- 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