QT4 CG Meeting 159 Minutes 2026-04-07
Meeting index / QT4CG.org / Dashboard / GH Issues / GH Pull Requests
Table of Contents
Summary of new and continuing actions [0/8]
[ ]QT4CG-143-02: MK to try to recover the ability to extract formal equivalences into tests[ ]QT4CG-144-01: MK to consider if any now lost value comparisons should be added as examples.[ ]QT4CG-150-04: NW to see about a status update on PR #2345; possibly schedule discussion[ ]QT4CG-156-01: MK: add reference to data model in F&O 9.2[ ]QT4CG-156-03: MK to revise PR #2516 in light of the comments.[ ]QT4CG-158-01: MK to revisit the Conformance section to revise in light of #2556 error changes[ ]QT4CG-158-02: MK to addsystem-properties()keys for file and binary support
Draft Minutes
1. Administrivia
1.1. Roll call [7/10]
Regrets: JK, JWL
[X]David J Birnbaum (DB)[ ]Reece Dunn (RD)[X]Christian Grün (CG)[ ]Joel Kalvesmaki (JK)[X]Michael Kay (MK)[X]Juri Leino (JLO)[ ]John Lumley (JWL)[X]Alan Painter (AP[X]Wendell Piez (WP)[X]Norm Tovey-Walsh (NW) Scribe. Chair.
1.2. Accept the agenda
Proposal: Accept the agenda.
1.3. Approve minutes of the previous meeting
Proposal: Accept the minutes of the previous meeting.
Accepted.
1.4. Next meeting
The next meeting is planned for 14 April 2026.
JWL gives regrets. AP is at risk.
1.5. Review of open action items [3/10]
[ ]QT4CG-143-02: MK to try to recover the ability to extract formal equivalences into tests[ ]QT4CG-144-01: MK to consider if any now lost value comparisons should be added as examples.[X]QT4CG-150-01: NW to ask Jirka for a room at XML Prague for Tuesday/Wednesday- Done.
[ ]QT4CG-150-04: NW to see about a status update on PR #2345; possibly schedule discussion[ ]QT4CG-156-01: MK: add reference to data model in F&O 9.2[ ]QT4CG-156-03: MK to revise PR #2516 in light of the comments.[X]QT4CG-157-01: CG to consider the issue of such empty directories[X]QT4CG-157-02: CG to propose an editorial change to use the fos:notes construct for the Notes. Also relevant to #2546[ ]QT4CG-158-01: MK to revisit the Conformance section to revise in light of #2556 error changes[ ]QT4CG-158-02: MK to addsystem-properties()keys for file and binary support
1.6. Review of open pull requests and issues
This section summarizes all of the issues and pull requests that need to be resolved before we can finish. See Technical Agenda below for the focus of this meeting.
2. Technical agenda
2.1. PR #2566: 1979 Records with type annotations
See PR #2566.
MK introduces the PR; it’s not ready for merging but there are some open issues to discuss.
- MK: This started with the desire to report static errors on records if you use fields inappropriately.
- … My first attempt introduced some static type checking; but that’s the thin edge of a very large wedge.
- … What happens if we handle records differently from maps?
- … Then we can make it an error to attemp to get a field that isn’t in the type.
- … For that, we need to make records a subset of maps (a separate type).
MK begins with the data model.
- MK: A record is a map item who’s keys and values are constrained by a record type definition.
- … Records get added to the type hierarchy diagram
- … Records now have a type annotation, so we have to tweak the definition of “type annotation”.
- … New section, 8.3 Records
- … The
getandputoperations on records are constrained- … CG proposes that
map:putandmap:getshould respect substitutability and we need new operators
- … CG proposes that
- … Not mentioned here, records no longer define optional fields
- … That means you don’t have to consider the difference between a missing field and a field with a value that is the empty sequence
- … The
Next, the XQuery spec.
- MK: Records and record types have a definition.
- … And we need a definition of
instance of. - … What I’ve done is still based on the content of the record. (So a map matches if it satisfies the constraints; rather than checking the type annotation.)
- … But
instance of, where we have it elsewhere, tends to be based on the type annotations. - … Using this formulation, avoids complications in XSLT for matching.
- … If there’s a constructor function for the record type, then it does so by invoking the coercion mechanism.
- … Record types may be named or anonymous.
- … There are record types defined in the
fn:namespace.
- … And we need a definition of
- MK: The binary tree example changes because the fields are no longer optional, but they may be empty.
- MK: The subtyping rules change because there’s no longer the concept of optional fields.
- … They’re still structural. This might be impacted if we based types on the names.
- MK: Looking at the coercion rules…
- … A map J is converted to a record R.
- … For every field declaration, the record will contain an entry for that field.
- … Extra fields are discarded.
- MK: Lookup expressions change to return a type error because they’re based on
map:get()- … But you don’t get the error for path expressions because historically they don’t give errors if they don’t exist.
- MK: Not allowing optional fields simplifies things.
In Functions and Operators:
- MK: It’s basically changes to individual functions.
- … Optional fields (in, for example, parse-uri, are no longer optional, they’re only emptiable)
- … These changes are all a consequence of basic model changes.
Discussion:
- NW: What about map:merge and other features that combine maps?
- MK: Those functions return maps.
- JLO: I wouldn’t want to confine things.
2.2. What about get and put?
- CG: I proposed in one of the previous issues to allow
map:getandmap:putand raise errors.- … I think it could be interesting to have
map:putalways return a map.- … But we could add a
withkeyword to explicitly modify record entries.
- … But we could add a
- … For
map:getI think it makes sense. - … Removing optional and emptiable record types makes a lot of sense.
- … I think it could be interesting to have
- JLO: I agree, merging these feels much better.
- AP: We were talking about having the lookup operator being different from
map:get. Why would that be? - MK: It is currently equivalent, but it is the most common way of doing access
to a statically named field of a record. Wheras, you tend not to use that when
the key is dynamically calculated; that’s where
map:getis used. So having them be equivalent doesn’t make perfect sense with usage patterns. - AP: There could be some surprise to see the difference. That will have to be spec’d carefully.
- WP: A few examples would be good.
- MK: I’ll try to work through making the lookup operator and
map:getdistinct.- … And I’ll try to incorporate the proposed
withoperator…
- … And I’ll try to incorporate the proposed
2.3. What about instance of?
- CG: If we changed the semantics, would it be limited to named records?
- MK: I don’t think so.
- … There is a question about whether you change the subtyping rules. If you change those to be based on naming, then you’d have to introduce the “extends” concept to say that one record type is a subtype of another and base it on that.
- MK: I’m slightly unsure, but I think you could move to type annotation based
instance of, but still do a structural comparison for subtyping.
- … You can say that a record is a complex number because it was instantiated that way…but does that make it an instance of a subtype?
- MK: We also need to think through how to do XSLT pattern matching.
- NW: I think the structural comparison is fine; is there something I’m missing?
- MK: It’s more of an intuition; if a thing is labeled with a type, we use that
for
instance ofelsewhere.- … I don’t think what I’ve done is unworkable.
- JLO: If
instance ofis based on named types, could this be cascade? If something doesn’t have the type label, would it also be an instance of? - MK: No, it wouldn’t be an
instance of, but it would match in some looser sense.- … I’ve sometimes been tempted to add “coerciable as”!
- JLO: How about two separate definitions of the same shape but both are anonymous; are those then instance of each other?
- MK: Only if we have structural typing, or if we have syntax for declaring a type hierarchy of named record types.
The group offers general encouragement to MK to press on!
- WP: I’m not sure that we need named based typing; we should leverage what we have. Stricter typing down deep is nice, but having more flexibility is also good.
- MK: One of the primary use cases here has to be JSON processing. When we parse
JSON, we aren’t going to get strictly typed results in any sense.
- … Those will be maps; we need to make it easy to invoke something more strongly typed.
JLO suggests that Elixir, an Erlang data binding language, for exploring JSON data binding.
2.4. PR #2572: 2312 Drop map:keys-where
See PR #2572.
MK introduces the PR. “You either like this or you don’t.”
- MK: Motivated by an issue that CG has raised about having too many ways to do things.
- … I thought we could get rid of this one, but CG says no, this is the one he wants!
- MK: All the proposal does is drop it.
MK reviews the rational in the PR. There are about four ways to do it without map:keys-where.
- CG: That’s fine to me. It was meant to be symmetric with
index-wherewhich we might also be able to do in several ways. It’s not obvious to use this function. - NW: That’s my thinking; I’d probably do something else before I remembered
that
fn:keys-whereexists.
Proposal: accept this PR.
Accepted.
2.5. PR #2570: 2553 File Module: delete empty directories
See PR #2570.
CG introduces the PR.
- CG: What should you do with
file:deleteif you pass an empty directory without the recursive option. - JLO: Even though it clarifies what the current spec says; I’d prefer to say the recursive flag is always required.
Proposal: accept this PR.
Accepted.
3. Any other business
- NW: Show of hands, who thinks they’ll attend the face-to-face meeting before XML Prague?
About six hands went up.
- DB: Can we avoid a scheduling conflict with XProc?
- NW: Alas no.