QT4 CG Meeting 013 Minutes 2022-11-29

Table of Contents


Approved at meeting 014 on 6 December 2022.

Summary of new and continuing actions [1/4]

  • [ ] QT4CG-002-10: BTW to coordinate some ideas about improving diversity in the group
  • [ ] QT4CG-013-01: MK to refine the coercion rules with respect to enumeration types
  • [ ] QT4CG-013-02: DN to provide a concrete example of the function case discussed with respect to coercion rules.
  • [X] QT4CG-013-03: MK to raise a separate issue about sequence/array out-of-bounds handling

1. Administrivia

1.1. Roll call [8/13]

Regrets BTW, JL

  • [ ] Anthony (Tony) Bufort (AB)
  • [X] Reece Dunn (RD) [0:30-]
  • [X] Christian Grün (CG)
  • [X] Joel Kalvesmaki (JK) [0:10-]
  • [X] Michael Kay (MK)
  • [ ] John Lumley (JL)
  • [X] Dimitre Novatchev (DN)
  • [X] Ed Porter (EP)
  • [ ] Liam Quin (LQ)
  • [ ] Adam Retter
  • [X] C. M. Sperberg-McQueen (MSM)
  • [ ] Bethan Tovey-Walsh (BTW)
  • [X] Norm Tovey-Walsh (NW). Scribe. Chair.

1.2. Accept the agenda

Proposal: Accept the agenda.


1.3. Next meeting

1.4. Approve minutes of the previous meeting

Proposal: Accept the minutes of the previous meeting.


1.5. Review of open action items [7/8]

  • [ ] QT4CG-002-10: BTW to coordinate some ideas about improving diversity in the group
    • Continued
  • [X] QT4CG-012-01: MK to add a reference to the place in XSD where it says that value spaces are non-overlapping
  • [X] QT4CG-012-02: MK to point out the rules for union types are actually a bit more complex than described in section 2.2.1.
  • [X] QT4CG-012-03: MK to consider introducing schema element and schema element in 2.8
  • [X] QT4CG-012-04: MK to add “and also of other specific function types” to 2.8.
  • [X] QT4CG-012-05: NW to see if the presentation of the type hierarchy tables can be improved.
  • [X] QT4CG-012-06: MK to remove xs:untyped from the paragraph at the top of 2.8.2
  • [X] QT4CG-012-07: NW to work with MK to sort out the server build issues with PR #237
    • Resolved, merged
  • [X] QT4CG-012-08: NW to put the coercion rule changes on the agenda next week.

2. Technical Agenda

2.1. Review the coercion rules

See 4.4.3 Coercion Rules in XPath 4.0

See also pull request #254

Mike walks us through the spec with the applied changes (the diff is a bit messy).

  • MK: Function conversion rules are renamed coercion rules
    • … Rules accept, coerce, or reject a supplied value
    • … (We’re reviewing the XQuery version, not the XPath version, so there are no sections about backwards compatibility.)

ACTION QT4CG-013-01: MK to refine the coercion rules with respect to enumeration types

Mike walks through the rules in 4.4.3

  • MK: Rule 5 is new: relabels types. This allows you to use “5” where xs:positiveInteger is expected without an explicit cast.
    • Relabeling is not the same as casting
    • Numeric promotion and relabeling are mutually exclusive.
    • The next rule is also new, it applies coercion to all the values of a map.
    • Then function coercion
    • Else error.
    • Function coercion has a new item 2 that says that if the function you supply has a lower arity than the function that’s required, then you wrap it in a function that ignores the excess arguments.
      • This lets callbacks that expect 1 argument to work with functions that could have two.
  • DN: When talking about coercion, it seems to me that the way I read it is that coercion applies only to the arguments, not the return value.
  • MK: No, this section doesn’t say where coercion is used.
  • DN: It kind of implies it though. Maybe we need to have a more explicit statement that it can be used for both.
  • MK: I wanted to avoid enumerating all the places where it’s used because they’re subject to change.
    • … In places like, for example, dynamic function calls, we say that the rules are applied to both the arguments and the return value.
  • MSM: I think if you look at, that makes the context for the term “supplied value” to make sense.
  • DN: It would still be good to be clear.
  • DN: When a function returns a function and the returned function has to be passed arguments, when are the arguments coerced? Is it done “early” or “late”?
    • … If we know some arguments won’t be used at all, can we assume that in this case, the arguments should not be evaluated “early”?
  • MK: I’m not sure I understand exactly the scenario you’re describing. This is a spec, not an implementation, so there’s plenty of scope for optimization.
  • DN: It’s definitely explicit somewhere in this text, maybe we should make sure it’s explicit in this case where a function that’s returned with a smaller arity gets wrapped.
  • CG: If a function item is returned, then we have potential paremeters, but no arguments.
  • DN: We have an expression; on the left side, the first thing that happens is a funtion is returned, and then the rest of the expression is the arguments for the function.
  • MK: Isn’t that just a simple optimization that implementations can perform?
  • DN: We should clearly say in this case that it is possible not to evaluate the arguments that are not going to be used.
  • NW: Can you provide an example in chat? We’re having trouble following just verbally?
  • DN: Yes, but maybe not now.

Some further attempt to describe examples.

ACTION QT4CG-013-02: DN to provide a concrete example of the function case discussed with respect to coercion rules.

  • NW: I don’t think anyone thinks you should be forbidden from throwing it away. Requiring it be thrown away might be possible.
  • MSM: I’d be a little nervous about a rule that says you are required to throw away an “extra” argument because I view lazy or eager evaluation as an optimization strategy.

MK draws our attention to another part of the spec.

  • MK: The coercion rules are also applied to variable bindings. In 4.15.1, there’s a new section that describes the coercion. (So let $temp as xs:double := 32.5 will succeed.)
    • … I proposed this before (years ago) and there was some objection because variables and functions are different and should be treated differently.
    • … I’ve looked at some other languages and there is some variation, but there’s no reason to think this should be a problem. It works fine in XSLT.
  • MSM: Makes sense to me: functions and constants and variables are all functions.

MSM draws our attention back to 4.4.3.

  • MSM: Can I come back to rule 5? In the Data Model, we’ve followed the lead of XSD in saying the value spaces of the primitive types are decreed to be distinct. That applies only to the primitive types. What I think we’re saying here is the type coercion to a subtype works if the required type and the label on the supplied value are both descended from the same primitive type.
  • MK: Yes, essentially.
  • MSM: So this covers integer/positiveInteger but not decimal/double.MK
  • MK: Or hexBinary to base64binary.

Some chuckling about the way this played out in XSD.

  • MK: If we’re going to take advantage of this capability to change standard functions, a function that expects an NCName for example, what I’ve suggested is that we give ourselves the license to declare the expected type as NCName and retain the error code if you give something else. Rather than getting a generic type error, we have the ability to define a more specific error code.
  • MSM: That seems to mean that that particular kind of type checking, raising those errors, has to take place before the coercion and not after it. The point of view has to be from outside the function.
  • MK: At the implementation level, there has to be some sort of secret sauce in the function signature to identify the error code.

Proposal: Accept this PR.


2.2. Review pull request #250: fn:foot, etc.

See pull request #250

Mike walk us through the PR.

  • MK: This gives us four new functions: fn:foot and fn:truncate and array:foot and array:truncate. They’re the same except for error checking where they’re consistent with related functions.
  • JK: Do these qualify in the category of “convenience functions”?
  • MK: They certainly do fall into that category. It’s easy to code them up yourself.
    • … For convenience functions you have to weigh two factors: how many folks are going to use them and how many lines/how difficult it is. The fn:head function saves a lot of people a lot of code. The fn:foot function probably saves fewer people just a little bit more code.
    • … It also makes the code easier to read; the last() trick for fn:foot is harder to understand and harder to optimize.
  • JK: They’ll be great functions to have, I’m just thinking of the larger question of the “cluttering” of the core specs with convenience functions.

NW observes that the question of issue #274 isn’t on the agenda this week, maybe it should be next week.

  • RD: One of the arguments against convenience functions is that it makes more work for implementors to claim conformance.
    • … I wonder if it would make sense to have a reference implementation for as many as we can, perhaps non-normatively.
  • EP: I was going to make exactly that point.
  • MSM: These functions do have those expressions.
  • RD: So we could pull that into a single place, grouped by XQuery and XSLT style.
  • MSM: A library that an implementation could just import.
  • DN: If the question is asked about fn:head and fn:tail, I don’t think they’re convenience functions at all! They’re the basics for any recursive implementation. And that holds true for these functions as well as they’re the complement of those functions.
    • … I am still firmly agains the name fn:truncate.
    • … I also don’t like the difference in behavior between the array and sequence versions. I proposed that for the sequence functions, we have an additional parameter that says whether an exception should be raised for an empty argument. The default value should be false(), but a user who wants them to behave the same as arrays can set them to true().
  • RD: An extra argument to control exception behavior isn’t a great design decision. It pollutes the argument namespace. It would make more sense to use something like the XQuery declare options.
  • MK: A mode like “unordered”. Make it part of the static context.
  • CG: Whenever you work with arrays, you always have out-of-bounds issues, we shouldn’t restrict it to just these functions.
  • DN: There’s no way to make an array behave like a sequence. An array can contain an empty sequence and that makes the cases indistinguishable.
  • RD: Then what happens if you’re writing the function and you have one case where you’ve remembered to include that parameter and another where you’ve forgotten it. Your code is expecting it to throw, but because you left it out, it doens’t. That’s my objection to having this as a parameter on each of the non-array functions.
  • DN: I think this is completely new behavior, but you’re right, you have to specify it in every call.
  • RD: Having it at the global level would allow you to have more consistent control, so you don’t have to remember to pass the specific parameter.
  • DN: But there could be cases where I want them to work both ways.
  • RD: But by extension, why not parameters on every function?
  • CG: We should separate this discussion from these four functions, they apply much more widely.

Some discussion of what other functions have this behavior.

  • NW: Why not wrap the function you want to check in another function that checks?
  • MSM: That has the value of being shorter and easier to remember.
  • MK: What are the possible solutions?
    • Do nothing, leave it up to the user; try/catch
    • Add parameters to the functions
    • Provide mirror versions of the functions
    • Make it modal
  • DN: Try/catch is the least practical
  • MM: My choice is the proposal as it’s designed: sequences are designed to be relaxed, arrays are for stronger type hecking. That inconsist

ACTION QT4CG-013-03: MK to raise a separate issue about sequence/array out-of-bounds handling

3. Any other business

None heard.