This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 29263 - [XQ30] if expression: optional else branch?
Summary: [XQ30] if expression: optional else branch?
Status: RESOLVED WORKSFORME
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XQuery 3.1 (show other bugs)
Version: Candidate Recommendation
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Jonathan Robie
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-11-05 10:25 UTC by Christian Gruen
Modified: 2015-11-10 17:26 UTC (History)
3 users (show)

See Also:


Attachments

Description Christian Gruen 2015-11-05 10:25:42 UTC
Over the years, I have seen hundreds of XQuery code snippets in which the else branch of the if expression was an empty sequence:

  if(...) then ... else ()

Besides that, people seem to be regularly confused that both "then" and "else" is needed (because it's not required in many other languages).

Motivated by the comfortable relaxation of EnclosedExpr, I think it would be great if we could make the else branch optional as well:

  IfExpr ::= "if" "(" Expr ")" "then" ExprSingle ("else" ExprSingle)?

As far as I can judge, the change in the grammar wouldn't cause any new ambiguities.
Comment 1 Michael Kay 2015-11-05 13:09:40 UTC
Don't you immediately hit the classic "dangling else" ambiguity?

if (a=b) then if (c=d) then x else y

I remember spending the best part of a day debating alternatives for if-then-else at a F2F, and one thing that we agreed on was that we didn't want to allow the dangling else ambiguity - which meant either that the else clause should be mandatory, or there should be an "end-if" or "fi" terminator. And people preferred to require "else ()" than to require "end-if".
Comment 2 Christian Gruen 2015-11-05 14:37:28 UTC
Michael, thanks as usual for the summary. I already feared that much time was already spent on this discussion a long time ago... I brought this up, as I experienced that many users would be glad to have the relaxation.

> Don't you immediately hit the classic "dangling else" ambiguity?
>
> if (a=b) then if (c=d) then x else y

When mentioning ambiguities, I only thought of syntactical parsing issues. Interestingly, the semantical ambiguity you have mentioned seems like a non-issue to me, maybe because it exists in many other languages as well, and because you can simply use parentheses...

  if (a=b) then (if (c=d) then x) else y

...to enforce a certain execution (what you would do as well when e.g. using and/or). This makes sense anyway, I believe, because

  if (a=b) then if (c=d) then x else y else ()

is not easy to read either. One might argue that wrong indentations lead to an erroneous interpretation of a query...

  if (a=b)
  then
    if (c=d)
    then x
  else
    y

...but this might as well occur with other expressions:

  a and
    b or c

But as you indicated, all of these arguments had probably been brought up earlier, so I will be completely fine to see this bug closed soon again.
Comment 3 Jonathan Robie 2015-11-05 15:13:09 UTC
I think a lot of people really wish that the else clause were optional. It's awkward in a lot of queries.

Christian's comment #2 makes sense to me, but to make this change, we would have to get consensus VERY quickly, be sure that it is well understood, and get test cases to illustrate it.

What would be sufficient evidence that we understand this well enough to make the change?
Comment 4 Michael Kay 2015-11-05 15:40:43 UTC
I think this is too late in the day.

I for one don't think that the change is necessarily simple, or necessarily desirable.

While it's true that other languages have resolved the dangling else ambiguity using an ad-hoc disambiguation rule, I don't think that necessarily makes it the right thing to do.
Comment 5 Jonathan Robie 2015-11-05 15:43:19 UTC
(In reply to Michael Kay from comment #4)
> I think this is too late in the day.

Quite likely, but I'd like to at least discuss it quickly before killing the idea.

> I for one don't think that the change is necessarily simple, or necessarily
> desirable.
> 
> While it's true that other languages have resolved the dangling else
> ambiguity using an ad-hoc disambiguation rule, I don't think that
> necessarily makes it the right thing to do.

It does seem to work. And while it's not perfect, it seems more desirable than requiring the else clause, which is rather a wart on the language.
Comment 6 Josh Spiegel 2015-11-05 15:58:17 UTC
I see this pattern sometimes:

  <root>{
      if ($var/foo) then
         <e>{$var/foo/data()}</e>
      else (),
      if ($var/bar) then
         <f>{$var/bar/data()}</f>
      else (),
      ...
  }</root>

I think it would be more readable without the "else()":

  <root>{
      if ($var/foo) then
         <e>{$var/foo/data()}</e>
      ,
      if ($var/bar) then
         <f>{$var/bar/data()}</f>
      ,
      ...
  }</root>

But this has failed to get through the working group at least twice.  Here is one discussion I found:
https://lists.w3.org/Archives/Public/public-qt-comments/2004Jan/0378.html

And I remember pushing for it when scripting was still on the table.  In the case of scripting there was another ambiguity where "else()" could be interpreted as a function call.  But I don't think this is an issue without scripting extensions.
Comment 7 Michael Kay 2015-11-05 16:12:20 UTC
Why did we decide that an InitialClause in a FLWOR expression should be mandatory? 

Without that rule, we could write

where $var/foo return $var/foo/data()
Comment 8 Abel Braaksma 2015-11-06 16:55:30 UTC
This was raised against XQ31, but sounds more like an XP31 bug to me?

Anyway, fwiw, I've often stared cluelessly at a complex expression with a syntax error, only to find out at some point that I forgot the redundant "else ()".

I think it is a good suggestion, it has no backward compatibility issues and the language production changes seem unambiguous. I'm sure many people will be grateful for being able to omit the mandatory 7 keystrokes. Whether its really small enough to warrant inclusion at this stage I don't know.

Conversely, it makes me wonder why in XSLT there's an xsl:if *without* an xsl:else, it doesn't even exist (but we have xsl:choose as a clumsy workaround, which XPath does not have).
Comment 9 Jonathan Robie 2015-11-10 17:26:15 UTC
It's too late in the game to make this change.  Some members also said they prefer the current design.