A question about the type system
Hello!
I'm not sure whether this is a question relevant to BaseX or more generally to the XQuery community. Since I don't use other XQuery systems and it might be specific to the BaseX parser, I post it here first.
Why can't I specify xs:positiveIntegers as literals? Or why can't I treat xs:integers as xs:positiveIntegers? Consider a simple function that takes a xs:positiveInteger as input:
<code>
xquery version "3.0" encoding "UTF-8";
declare namespace local = "local";
declare function local:positive(
$input as xs:positiveInteger
) as xs:positiveInteger
{
$input
};
</code>I get an error XPTY0004 Cannot treat xs:integer as xs:positiveInteger if I run it with a literal input, like this:
<code>
local:positive(2)
</code>I get no error if I specify the type explicitly, like this:
<code>
local:positive(xs:positiveInteger(2))
</code>This feel very odd, since the type system is hierarchical and xs:positiveInteger is a subcase of xs:integer, I don't really see a problem of this kind of automatic casting of integer literals if they qualify the cast.
Can you give any reflection on this?
Best regards Kristian Kankainen
Hi Kristian,
Quoted text · Kristian Kankainen · 2 lines
> Why can't I specify xs:positiveIntegers as literals? Or why can't I treat > xs:integers as xs:positiveIntegers?
The error is correct. Type handling in XQuery is a topic on its own: Values can be cast, promoted, treated as, etc. in this language. If you want to dive into the details, I suggest having a look at the section on type promotion in the specification:
http://www.w3.org/TR/xquery-31/#id-type-promotion-and-operator-mapping
If you are looking for a practical solution, I advise you to simply use with xs:integer, even if a value will always be positive, or if it will have a smaller bit range. Most operations have been optimized for integers, so you won't lose any time for additional type conversion.
Hope this helps, Christian
Quoted text · Kristian Kankainen · 35 lines
Consider a simple function that takes a > xs:positiveInteger as input: > > <code> > xquery version "3.0" encoding "UTF-8"; > declare namespace local = "local"; > > declare function local:positive( > $input as xs:positiveInteger > ) as xs:positiveInteger > { > $input > }; > </code> > > I get an error XPTY0004 Cannot treat xs:integer as xs:positiveInteger if I > run it with a literal input, like this: > <code> > local:positive(2) > </code> > > I get no error if I specify the type explicitly, like this: > <code> > local:positive(xs:positiveInteger(2)) > </code> > > This feel very odd, since the type system is hierarchical and > xs:positiveInteger is a subcase of xs:integer, I don't really see a problem > of this kind of automatic casting of integer literals if they qualify the > cast. > > Can you give any reflection on this? > > Best regards > Kristian Kankainen
Hello!
Thank you very much, I will read. What I skimmed now, there exists *subtype substitution*, which would allow xs:positiveIntegers be automaticall cast to xs:integers, which is the opposite direction of my case. There exists also *type propagation*, which of one case allows any xs:decimal or subtype of it be cast into either xs:double or xs:float, which can result in a loss of precision.
I guess my intuition put together, that if it's possible to substitute with subtypes && it's possible to propagate from decimals to floats and doubles, then it ought to be possible to move also along the non-destructive parts of sub and supertypes. Nothing is ideal, atleast I can explicitly cast the return value as xs:positiveInteger.
PS for my further investigations, could you point me to the BaseX code for the pseudo-function named derives-from? Thank you!
Best regards Kristian
15.04.2015 16:19, Christian Grün kirjutas:
Quoted text · Christian Grün · 55 lines
> Hi Kristian, > >> Why can't I specify xs:positiveIntegers as literals? Or why can't I treat >> xs:integers as xs:positiveIntegers? > The error is correct. Type handling in XQuery is a topic on its own: > Values can be cast, promoted, treated as, etc. in this language. If > you want to dive into the details, I suggest having a look at the > section on type promotion in the specification: > > http://www.w3.org/TR/xquery-31/#id-type-promotion-and-operator-mapping > > If you are looking for a practical solution, I advise you to simply > use with xs:integer, even if a value will always be positive, or if it > will have a smaller bit range. Most operations have been optimized for > integers, so you won't lose any time for additional type conversion. > > Hope this helps, > Christian > > > Consider a simple function that takes a >> xs:positiveInteger as input: >> >> <code> >> xquery version "3.0" encoding "UTF-8"; >> declare namespace local = "local"; >> >> declare function local:positive( >> $input as xs:positiveInteger >> ) as xs:positiveInteger >> { >> $input >> }; >> </code> >> >> I get an error XPTY0004 Cannot treat xs:integer as xs:positiveInteger if I >> run it with a literal input, like this: >> <code> >> local:positive(2) >> </code> >> >> I get no error if I specify the type explicitly, like this: >> <code> >> local:positive(xs:positiveInteger(2)) >> </code> >> >> This feel very odd, since the type system is hierarchical and >> xs:positiveInteger is a subcase of xs:integer, I don't really see a problem >> of this kind of automatic casting of integer literals if they qualify the >> cast. >> >> Can you give any reflection on this? >> >> Best regards >> Kristian Kankainen
Quoted text · Kristian Kankainen · 2 lines
> PS for my further investigations, could you point me to the BaseX code for > the pseudo-function named derives-from? Thank you!
There is no direct relationship between functions in the spec and in BaseX, but you could e.g. have a look at the following function and classes:
https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/query/value/type/SeqType.java#L438 https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/query/expr/TypeCheck.java
Hope this helps, Christian
Quoted text · Kristian Kankainen · 63 lines
> 15.04.2015 16:19, Christian Grün kirjutas: >> >> Hi Kristian, >> >>> Why can't I specify xs:positiveIntegers as literals? Or why can't I treat >>> xs:integers as xs:positiveIntegers? >> >> The error is correct. Type handling in XQuery is a topic on its own: >> Values can be cast, promoted, treated as, etc. in this language. If >> you want to dive into the details, I suggest having a look at the >> section on type promotion in the specification: >> >> http://www.w3.org/TR/xquery-31/#id-type-promotion-and-operator-mapping >> >> If you are looking for a practical solution, I advise you to simply >> use with xs:integer, even if a value will always be positive, or if it >> will have a smaller bit range. Most operations have been optimized for >> integers, so you won't lose any time for additional type conversion. >> >> Hope this helps, >> Christian >> >> >> Consider a simple function that takes a >>> >>> xs:positiveInteger as input: >>> >>> <code> >>> xquery version "3.0" encoding "UTF-8"; >>> declare namespace local = "local"; >>> >>> declare function local:positive( >>> $input as xs:positiveInteger >>> ) as xs:positiveInteger >>> { >>> $input >>> }; >>> </code> >>> >>> I get an error XPTY0004 Cannot treat xs:integer as xs:positiveInteger if >>> I >>> run it with a literal input, like this: >>> <code> >>> local:positive(2) >>> </code> >>> >>> I get no error if I specify the type explicitly, like this: >>> <code> >>> local:positive(xs:positiveInteger(2)) >>> </code> >>> >>> This feel very odd, since the type system is hierarchical and >>> xs:positiveInteger is a subcase of xs:integer, I don't really see a >>> problem >>> of this kind of automatic casting of integer literals if they qualify the >>> cast. >>> >>> Can you give any reflection on this? >>> >>> Best regards >>> Kristian Kankainen > >
Written for BaseX 8.1. BaseX may have changed since: please check the current documentation.