Bugzilla – Bug 20631

[XQ31] The "numeric" pseudo-type

Last modified: 2014-11-11 16:25:27 UTC

A number of functions, such as abs(), have signatures that declare the expected type and result type as "numeric". In 4.2 we explain "The word " numeric " in function signatures signifies these four types [that is, integer, decimal, float, and double]." This informal description was fine in the past, but it falls apart once we have higher-order functions. What is the type of fn:abs#1? What happens when we supply fn:abs#1 to a function that expects function(xs:integer) as xs:double? We don't say. With the work that we have done on unions, we can do better than this. We should say that where we use "numeric" in a function signature, we mean an anonymous type whose definition is union(xs:decimal, xs:double, xs:float). With this definition, there is no change in functionality for callers of these functions, but the semantics become clear for higher-order operations where the type of the function is significant.

Actually, it should be union(xs:double, xs:float, xs:decimal) in that order. The current rule in the function calling rules that says <quote>For built-in functions where the expected type is specified as numeric, arguments of type xs:untypedAtomic are cast to xs:double.</quote> can then be removed; this will happen automatically by virtue of the existing rules applying to all union types. Because xs:double is the first type listed in the union, and because the lexical space of xs:double is a superset of the lexical space of xs:float and xs:decimal, the cast will always either return an xs:double, or will fail. So there is no change from the existing behaviour.

This issue is addressed in 3.1.6 Named Function References: Certain functions in the [XQuery and XPath Functions and Operators 3.0] specification are defined to be polymorphic. These are denoted as accepting parameters of "numeric" type, or returning "numeric" type. Here "numeric" is a pseudonym for the four primitive numeric types xs:decimal, xs:integer, xs:float, and xs:double. For the purposes of named function references, these functions are regarded as taking arguments and producing results of type xs:anyAtomicType, with a type error raised at runtime if the argument value provided is not of the correct numeric type. Note: The above way of modeling polymorphic functions is semantically backwards compatible with XQuery 1.0. An implementation that supports static typing can choose to model the types of these functions more accurately if desired.

Decided to put this on the 3.1 agenda and make no change for 3.0.

*** Bug 25444 has been marked as a duplicate of this bug. ***

I suggest that we replace this definition as follows: [Definition: When referring to a type, the term numeric denotes the types xs:integer, xs:decimal, xs:float, and xs:double<add>, which are each derived from xs:numeric</add>.]

(In reply to Jonathan Robie from comment #5) > I suggest that we replace this definition as follows: > > [Definition: When referring to a type, the term numeric denotes the types > xs:integer, xs:decimal, xs:float, and xs:double<add>, which are each derived > from xs:numeric</add>.] I will also have to look at all uses of numeric in XQuery 3.1 / XPath 3.1.

(In reply to Jonathan Robie from comment #6) > (In reply to Jonathan Robie from comment #5) > > I suggest that we replace this definition as follows: > > > > [Definition: When referring to a type, the term numeric denotes the types > > xs:integer, xs:decimal, xs:float, and xs:double<add>, which are each derived > > from xs:numeric</add>.] > > I will also have to look at all uses of numeric in XQuery 3.1 / XPath 3.1. xs:double etc are not "derived from" xs:numeric, at least not in the sense of XSD 1.1 part 2 where "A is derived from B" means "The base type of A is B or is a type derived from B". xs:double is substitutable for xs:numeric, which is not the same thing.

It makes me nervous to say that xs:integer et al. are "derived from" xs:numeric, since that would set up a direct conflict with the use of the term "derive" in XSD (in which xs:numeric, like all unions, is "derived from" xs:anySimpleType). I think we would do better to follow the wording used to introduce the type in F and O, and say something like: [Definition: When referring to a type, the term xs:numeric denotes the built-in type xs:numeric, which is a union of (in order) the types xs:double, xs:float, and xs:decimal.] I am aware that there are parts of the XSD spec that use "derived" in precisely the way I am here cautioning against; experience with the utility of those usages is one reason I am expressing my concern about this.

The definition now reads as follows: [Definition: When referring to a type, the term numeric denotes the types xs:integer, xs:decimal, xs:float, and xs:double which are all member types of the built-in union type xs:numeric .]