• Subject: Re: Ternary operator patch
• From: David Manura <dm.lua@...>
• Date: Fri, 17 Sep 2010 23:11:36 -0400

```To summarize some of this discussion...

On Thu, Sep 9, 2010 at 9:04 PM, Ryota Hirose <hirose.ryota@gmail.com> wrote:
> a = if x == y then good() else bad()

On Fri, Sep 10, 2010 at 5:01 PM, Roberto Ierusalimschy
<roberto@inf.puc-rio.br> wrote:
> I have an issue, but I am not sure it is a "long-term" one. I think
> the proposed syntax, without "end", will be quite confusing to some
> people, given that the almost identical if command must have "end".
> On the other hand, a syntax with "end" is cumbersome.

On Sat, Sep 11, 2010 at 12:13 AM, David Manura <dm.lua@math2.org> wrote:
> On Fri, Sep 10, 2010 at 5:15 PM, Patrick Donnelly <batrick@batbytes.com> wrote:
>> a = b then x else y
> That is problematic, as pointed out by Fabien [1].  Compare:
>  if a then b() else c() then d() end -- confusing
>  if if a then b() else c() then d() end -- ok

On Sat, Sep 11, 2010 at 12:13 AM, David Manura <dm.lua@math2.org> wrote:
> return if x then f() else z .....
> That also deceptively looks like a "postfix if" [2] as in Perl

On Wed, Sep 15, 2010 at 5:26 AM, Fabien <fleutot+lua@gmail.com> wrote:
> I would argue that it is inconsistent with the Lua-wide convention that the
> "end" keyword terminates a block of statements, never an expression.

That said, I suggest instead the syntax

a = (x then y else z)

where "if" and "end" keywords are both omitted, but parenthesis are
required.  The argument for this, first, is that the above statement
will be perfectly clear to the novice, somewhat more clear in ways
than Ryota's syntax due to precedence reasons and much more clear than
"a = x and y or z".  Style guides may recommend the programmer use
parenthesis here anyway for clarity.  If parenthesis then are always
used, then the "if" is no longer needed to resolve a grammar
ambiguity, and removing it eliminates the asymmetry of an "if" without
a matching "end" and makes it look more like an operator in the manner
of and/or.  It also is one character *shorter* than the "if x then y
else z" form.  We avoid adding another precedence level or a new
keyword.  The parenthesis around statement keywords also has
similarities to what a list comprehension syntax might look like in
Lua: e.g. {x^2 for x=1,10}.

Concerning clarity of Ryota's syntax, consider coming across some
poorly formatted code like this:

if a and if b then c() else d() then
return
if u then v() else w() end

A novice might initially start reading it something like this:

(if a and if b) then c() else d() then;
return;
if u then v() else w() end

if a and (if b then c() else d()) then
return
(if u then v() else w()) end

Omitting "if" arguably even further improves clarity by making the
construct look more like an expression rather than the statement that
it is not:

if a and (b then c() else d()) then
return
(u then v() else w()) end

You may also allow omitting "then" or "else" clauses and using "elseif":

x = (x else 1)
f((x then y))
f{(u then v), (a then b elseif c then d else e)}

The first two are slightly different than the or/and forms in that
they would mean

x = (x then nil else 1)  -- not: x = (x then x else 1)
f((x then y else nil))     -- not: f((x then y else x))

Although allowing omission of the parenthesis like `f(x then y)` is
unambiguous, it might reduce clarity too much in the third example.
By requiring parenthesis, expressions lists inside the conditional
will also be clear:

(x then f() else y, z)

but it does conflict with the idea that parenthesis around an
expression list converts it to a single expression value, and it might
conflict with a possible tuple syntax.

```