expath / xpath-ng

Wishlist for XPath Syntax Extensions
Creative Commons Attribution 4.0 International
12 stars 4 forks source link

Switch Cases: Lift single-item restriction on operands #12

Closed ChristianGruen closed 1 year ago

michaelhkay commented 6 years ago

I think you need to explain what the proposed semantics are. After looking at it for a while I guess that your proposed semantics are either (a) the case matches if any item in the operand sequence is equal under the "eq" operator, or (b) (almost but not quite the same) to use the "=" operator. Or it might be something completely different: I'm guessing.

ChristianGruen commented 6 years ago

Thanks for asking. It’s good to know that the solution is not so obvious as we thought it would be.

Our suggestion is to rephrase the current matching rules as follows:

  1. The SwitchCaseOperand is evaluated.
  2. The resulting value is atomized.
  3. The atomized value of the switch operand expression is compared with each item of the atomized value of the SwitchCaseOperand using the fn:deep-equal function, with the default collation from the static context.

Rule 1 and 2 are identical. The old rule 3 is dropped, and rule 4 is slightly rewritten.

In a nutshell, it shouldn’t make a difference anymore if a single case or if multiple case operands are used if the returned value is the same.

Feel free to ask for more details.

michaelhkay commented 6 years ago

That makes sense. I wouldn't have put this enhancement high on my list of priorities, but it seems unproblematic and no doubt useful to some.

ChristianGruen commented 6 years ago

True, it doesn’t have a very high priority for us either. I just thought I make the suggestion after two different users had stumbled across this case.

adamretter commented 6 years ago

@ChristianGruen Seems like a nice simple enhancement to me

ChristianGruen commented 6 years ago

While implementing a proof of concept, I got reminded of another idiosyncracy of the switch expression in XQuery: If the switch expression yields an empty sequence, it’s not necessarily the default branch that will be chosen. Empty case operands are valid as well:

switch (())
  case ()
    return 'this-branch-will-be-chosen'
  default
    return error()

This would further complicate my proposal, as we would need to treat the empty sequence as a special case (any other solution, as far as I can judge, would endanger the backwards-compatibility). Please note that it can make a difference if case A case B is rewritten to case (A, B).

The updated rules could be as follows:

  1. The SwitchCaseOperand is evaluated.
  2. The resulting value is atomized.
  3. The case matches if the value is empty and if the value of the switch expression is empty as well.
  4. Otherwise, the atomized value of the switch operand expression is compared with each item of the atomized value of the SwitchCaseOperand using the fn:deep-equal function, with the default collation from the static context.

I would still be in favor of keeping the proposal alive (as it seems rather esoteric to me to check for empty sequences via switch), but I can understand if some of you tend to reject the proposal for that reason.

michaelhkay commented 6 years ago

Ouch. We have far too many flavours of equality testing already, this seems to be adding another. (Funny how the simplest changes to the language often turn out on examination to have subtle gotchas. Well done for spotting this one.)

Part of the problem here is the use of deep-equal() to compare two atomic values. It's logical in the sense that it gives the right semantics, but it's unintuitive. Using the is-same-key relation would have been better, but it's too late to change that.

ChristianGruen commented 1 year ago

Closed; see https://github.com/qt4cg/qtspecs/issues/328