-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support general union sequence types #122
Comments
What is the effect on the type subsumption rules, that is the judgements What is the effect on the function conversion rules? What is the effect on XSLT patterns? Generally I'm sympathetic to the proposal. The current proposal to allow unions only over atomic types is a relatively timid compromise, motivated by the fact that schema-defined union types are already supported. This more ambitious proposal certainly meets additional requirements. I'm slightly concerned though at the amount of detail that will need to be worked through, for example the effect on the function conversion rules. |
The effective case in the typeswitch section is defined as:
In order to make that fit this proposal, the wording should be updated to something like:
3.7.2 The judgement subtype-itemtype(A, B)For
3.7.1 The judgement subtype(A, B)This would be supported by something like:
|
What about (A|B) being a subtype of (A|B|C)? Also need to consider cast and castable. Which raises the question of whether the order is significant, consider |
I'm writing a new issue about that as the rules are currently broken when |
To make it easier to follow, I've edited the proposal above to include the text changes. This includes adding the case when |
Note also that with the way |
I would prefer to focus on unions of item types, excluding sequence types. I think that would remove a whole area of complexity, without significant loss of functionality. But are unions enough? For example, to represent the type J representing the result of |
I'm happy to split this into two issues -- unions of item types and unions of sequence types. As for the other part, I think I have an issue here around self-referencing/recursive item-types in the context of the I think that like with the variadic feature we should keep the successively more complex capabilities separate so we can at least get some of the functionality in place even if we don't get to cover all the use cases in this release. |
I'd like to refresh this issue and see if we can make progress. There are definitely use cases, for example defining a function that works on both maps and arrays. I'm a lot more comfortable defining general unions of item types rather than unions of sequence types. Mixing multiple cardinalities seems very disruptive in terms of type inference, subsumption rules, etc, and it's hard to identify convincing use cases. For general unions of item types, there's a decision to be made: should this generalize the existing concept of union types (and thus reuse the syntax Whereas it makes sense for atomic union types to have a constructor function that creates an instance of the first one of the member types "that works", this doesn't make sense for generalised union item types. However, the matching semantics are straightforward (X matches union(A, B) if X matches A or X matches B), and the itemType-subtype rules also seem to need no change except in terminology and examples: if A is a union type, then A ⊆ B if every type T in the transitive membership of A satisfies T ⊆ B . |
+1
+1
What’s the reason for having a constructor function of union types? Is it simply backward-compatibility? It feels confusing to me to be able to cast a value to a type that actually represents multiple times. |
Good question. I think the answer is that you want types defined using union to look as much like types defined by restriction as possible. For example if you define |
Maybe we could discuss that again. I’m still uncomfortable with having a |
I've been doing more work on this. I started off thinking that sequence type unions were sufficient, and we could manage without item type unions, but working it through, I don't think that's the case. There are definite cases where we need something like |
Use Case
There are a number of cases where it is beneficial to define a type more precisely (specifically in parameters and return types) as a union of item or sequence types, for example:
xs:hexBinary
andxs:base64Binary
;ol
orul
html list element names;xs:string*
) an element (element(options)
) or a map;There are a number of MarkLogic APIs that make use of this. Several EXPath and EXQuery specifications can take advantage of this. I've also used this in my XQuery IntelliJ plugin when defining vendor APIs that have changed over the different versions.
Examples
Existing Support
Note: Due to
SequenceTypeUnion
being present in typeswitch expressions XQuery implementations will have existing code to handle matching these unioned types.Syntax
3.4 Sequence Types
3.6 Item Types
Other Changes
Text
4.22.2 Typeswitch
The effective case definition is defined as:
In order to make that fit this proposal, the wording should be updated to something like:
3.7.2 The judgement subtype-itemtype(A, B)
Section (2) Conditions for atomic and union types: should add the following rules:
A
is anItemTypeUnion
in the form(T1 | T2 | ...)
and every typeT
in (T1
,T2
, ...) satisfiessubtype-itemType(T, B)
.B
is anItemTypeUnion
in the form(T1 | T2 | ...)
and any typeT
in (T1
,T2
, ...) satisfiessubtype-itemType(A, T)
.3.7.1 The judgement subtype(A, B)
The first paragraph in this section shall be replaced by:
The judgement
subtype(A, B)
determines if the sequence typeA
is a subtype of the sequence typeB
.A
can either beempty-sequence()
,xs:error
, an ItemType,Ai
, possibly followed by an occurrence indicator, or aSequenceTypeUnion
. SimilarlyB
can either beempty-sequence()
,xs:error
, an ItemType,Bi
, possibly followed by an occurrence indicator, or aSequenceTypeUnion
.The result of the
subtype(A, B)
judgement can be determined as follows:A
is aSequenceTypeUnion
in the form(T1 | T2 | ...)
and every typeT
in (T1
,T2
, ...) satisfiessubtype(T, B)
, thensubtype(A, B)
is true.B
is aSequenceTypeUnion
in the form(T1 | T2 | ...)
and any typeT
in (T1
,T2
, ...) satisfiessubtype(A, T)
, thensubtype(A, B)
is true.The text was updated successfully, but these errors were encountered: