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 add system-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 add system-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.

1.6.1. substantive PRs

The following substantive PRs were open when this agenda was prepared.

  • PR #2572: 2312 Drop map:keys-where
  • PR #2570: 2553 File Module: delete empty directories
  • PR #2566: 1979 Records with type annotations

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 get and put operations on records are constrained
        • … CG proposes that map:put and map:get should respect substitutability and we need new operators
      • … 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

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.
  • 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:get and map:put and raise errors.
    • … I think it could be interesting to have map:put always return a map.
      • … But we could add a with keyword to explicitly modify record entries.
    • … For map:get I think it makes sense.
    • … Removing optional and emptiable record types makes a lot of sense.
  • 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:get is 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:get distinct.
    • … And I’ll try to incorporate the proposed with operator…

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 of elsewhere.
    • … I don’t think what I’ve done is unworkable.
  • JLO: If instance of is 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-where which 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-where exists.

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:delete if 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.