Ternary operator patch

classic Classic list List threaded Threaded
129 messages Options
1234 ... 7
Reply | Threaded
Open this post in threaded view
|

Ternary operator patch

Ryota Hirose
Hello, lua-users,

Attached patch is a ternary operator patch for Lua 5.1.4.  I made it but I am not confidence that this patch is correct.
Could someone review my patch and point out any defect to me?

A syntax of ternary op. is if/then/else, so it is like haskell.  You can write a code as following:

a = if x == y then good() else bad()

c = string.char(x + (if x < 10 then string.byte('0') else string.byte('A') - 10))

A priority of if/then/else operator is lowest.

Thank you,
Ryota Hirose


lua-ifexpr.diff (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

steve donovan
On Fri, Sep 10, 2010 at 3:04 AM, Ryota Hirose <[hidden email]> wrote:
> a = if x == y then good() else bad()

Why not the good old-fashioned a = x == y and good() or bad() ?

steve d.

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Henk Boom-2
On 10 September 2010 01:56, steve donovan <[hidden email]> wrote:
> On Fri, Sep 10, 2010 at 3:04 AM, Ryota Hirose <[hidden email]> wrote:
>> a = if x == y then good() else bad()
>
> Why not the good old-fashioned a = x == y and good() or bad() ?

This doesn't work when it's possible for good() to return false or nil

    henk

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

steve donovan
On Fri, Sep 10, 2010 at 7:59 AM, Henk Boom <[hidden email]> wrote:
> This doesn't work when it's possible for good() to return false or nil

This is true, and I've been bitten by this one before.

a = x == y and (good() or true) or bad()

;)

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Geoff Leyland
On 10/09/2010, at 6:11 PM, steve donovan wrote:

> On Fri, Sep 10, 2010 at 7:59 AM, Henk Boom <[hidden email]> wrote:
>> This doesn't work when it's possible for good() to return false or nil
>
> This is true, and I've been bitten by this one before.
>
> a = x == y and (good() or true) or bad()

Does that still work if you want the false or nil from good()?


Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

steve donovan
On Fri, Sep 10, 2010 at 8:15 AM, Geoff Leyland
<[hidden email]> wrote:
> Does that still work if you want the false or nil from good()?

No!  So I'm convinced, it can't be done with the existing operators -
sorry for the noise.

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Miles Bader-2
steve donovan <[hidden email]> writes:
>> Does that still work if you want the false or nil from good()?
>
> No!  So I'm convinced, it can't be done with the existing operators -
> sorry for the noise.

Not only is the expression-if more correct, it's also more clear (when
an "if" is what you want to expression)...!

-Miles

[I admit, an if-else operator is something I've wanted quite a few times
in the past, and given the extremely small implementation cost, seems
like it's almost a no-brainer...]

-miles

--
People who are more than casually interested in computers should have at
least some idea of what the underlying hardware is like.  Otherwise the
programs they write will be pretty weird.  -- Donald Knuth

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

David Kastrup
Miles Bader <[hidden email]> writes:

> [I admit, an if-else operator is something I've wanted quite a few
> times in the past, and given the extremely small implementation cost,
> seems like it's almost a no-brainer...]

A child has an extremely small implementation cost as well.  You have to
keep the followup costs in mind.

--
David Kastrup


Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Miles Bader-2
David Kastrup <[hidden email]> writes:
>> [I admit, an if-else operator is something I've wanted quite a few
>> times in the past, and given the extremely small implementation cost,
>> seems like it's almost a no-brainer...]
>
> A child has an extremely small implementation cost as well.  You have to
> keep the followup costs in mind.

Hmm, given that it arguably could make much code _clearer_, the followup
costs may actually be less than zero... :)

[Note I'm talking about a simple "if EXPR then EXPR else EXPR", not
something fancy that allows embedded blocks or whatever.]

-Miles

--
Alliance, n. In international politics, the union of two thieves who have
their hands so deeply inserted in each other's pockets that they cannot
separately plunder a third.

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

David Kastrup
Miles Bader <[hidden email]> writes:

> David Kastrup <[hidden email]> writes:
>>> [I admit, an if-else operator is something I've wanted quite a few
>>> times in the past, and given the extremely small implementation cost,
>>> seems like it's almost a no-brainer...]
>>
>> A child has an extremely small implementation cost as well.  You have to
>> keep the followup costs in mind.
>
> Hmm, given that it arguably could make much code _clearer_, the followup
> costs may actually be less than zero... :)
>
> [Note I'm talking about a simple "if EXPR then EXPR else EXPR", not
> something fancy that allows embedded blocks or whatever.]

Do you really think you can keep children from growing up?

--
David Kastrup


Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Jonathan Castello-2
On Fri, Sep 10, 2010 at 2:42 AM, David Kastrup <[hidden email]> wrote:
> Do you really think you can keep children from growing up?

Can you be less cryptic please, and explain what you think the
long-term issues are? I think this is a useful addition too.

~Jonathan

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Roberto Ierusalimschy
> On Fri, Sep 10, 2010 at 2:42 AM, David Kastrup <[hidden email]> wrote:
> > Do you really think you can keep children from growing up?
>
> Can you be less cryptic please, and explain what you think the
> long-term issues are? I think this is a useful addition too.

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.

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Patrick Donnelly
On Fri, Sep 10, 2010 at 5:01 PM, Roberto Ierusalimschy
<[hidden email]> wrote:

>> On Fri, Sep 10, 2010 at 2:42 AM, David Kastrup <[hidden email]> wrote:
>> > Do you really think you can keep children from growing up?
>>
>> Can you be less cryptic please, and explain what you think the
>> long-term issues are? I think this is a useful addition too.
>
> 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.

I believe the "if" looks nice but is unnecessary and may be confusing.
Something like:

a = b then x else y

would be shorter (after all, isn't that the reason we do this?). I
think a better choice for the ternary operator keywords would make it
even clearer. I considered something like this:

a = x when b else y

That messes up the usual order so it's unlikely to be accepted.

For what it's worth, I'm definitely in the boat that we need a builtin
ternary operator. The "b and x or y" idiom is just too confusing to
newcomers. Most don't ever learn what it really means and get bitten
by bugs when x is false/nil.

--
- Patrick Donnelly

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Duncan Cross
On Fri, Sep 10, 2010 at 10:15 PM, Patrick Donnelly <[hidden email]> wrote:

> On Fri, Sep 10, 2010 at 5:01 PM, Roberto Ierusalimschy
> <[hidden email]> wrote:
>>> On Fri, Sep 10, 2010 at 2:42 AM, David Kastrup <[hidden email]> wrote:
>>> > Do you really think you can keep children from growing up?
>>>
>>> Can you be less cryptic please, and explain what you think the
>>> long-term issues are? I think this is a useful addition too.
>>
>> 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.
>
> I believe the "if" looks nice but is unnecessary and may be confusing.
> Something like:
>
> a = b then x else y
>
> would be shorter (after all, isn't that the reason we do this?). I
> think a better choice for the ternary operator keywords would make it
> even clearer. I considered something like this:
>
> a = x when b else y

Or even 'x if b else y' - even shorter and does not require a new keyword.

> That messes up the usual order so it's unlikely to be accepted.

I don't know, Lua is already relatively unusual in a lot of ways.

> For what it's worth, I'm definitely in the boat that we need a builtin
> ternary operator. The "b and x or y" idiom is just too confusing to
> newcomers. Most don't ever learn what it really means and get bitten
> by bugs when x is false/nil.

I think it's a good idea, too

-Duncan

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Alex Queiroz
Hallo,

On Fri, Sep 10, 2010 at 6:28 PM, Duncan Cross <[hidden email]> wrote:
>
> Or even 'x if b else y' - even shorter and does not require a new keyword.
>

     Please, let's avoid postfix operators a la Perl and Ruby.

--
-alex
http://www.artisancoder.com/

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Enrico Tassi-3
In reply to this post by Roberto Ierusalimschy
On Fri, Sep 10, 2010 at 06:01:28PM -0300, Roberto Ierusalimschy wrote:
> On the other hand, a syntax with "end" is cumbersome.

I find it nice instead, it just looks like if the if-then-else-end
construct had been promoted from the statement class to the expression's one.

Maybe I'm too biased by functional languages, but I very often type, by
mistake, "z = if b then x else y end"...

Cheers, and +1 for that "feature".
--
Enrico Tassi

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

David Manura
In reply to this post by Patrick Donnelly
On Fri, Sep 10, 2010 at 5:15 PM, Patrick Donnelly <[hidden email]> 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

> a = x when b else y
> That messes up the usual order so it's unlikely to be accepted.

This form also implies we can't use the "elseif" keyword in the usual way:

return x if a else
       y if b else
       z

> The "b and x or y" idiom is just too confusing to
> newcomers. Most don't ever learn what it really means and get bitten
> by bugs when x is false/nil.

I don't disagree, but the ternary operator might not eliminate such
idioms.  Looking at my own code, I have used and may continue to use
things like

  x = x or 1
    -- i.e. if x==nil then x = 1 end
    -- i.e. x = if x then x else 1

  local s2 = s and s:gsub(" ", "")
    -- i.e. local s2; if s ~= nil then s2 = s:gsub(" ", "") end
    -- i.e. local s2 = if s then s:gsub(" ", "") else nil

  print(t and t[1] and t[1].tag or 'notag')
    -- i.e. local v='notag'; if t and t[1] and t[1].tag then
v=t[1].tag end; print(v)
    -- i.e. if t and t[1] and t[1].tag then t[1].tag else 'notag'
    -- Here: the intention *is* to print 'notag' if t[1].tag is nil.

The ternary operator does lengthen the syntax, though not greatly and
not at the expense of clarity.

All forms do suffer, however, from the different problem of
reevaluation: in a chain of "<expr1> and <expr2> and <expr3> and ...",
we would prefer to allow expressions to refer to temporaries in
previous expressions:

  print(if t and t[1] as t1 and t1.tag as tag then tag else 'notag')
-- explicit naming
  print(if t and _1[1] and _2.tag then _3 else 'notag') -- implicit naming
  (Note: 5.2.0-work4 anonymous closure caching helps speed but not syntax.)

What about expression lists in ternary operators?  There's a question
of relative precedence to the comma:

  function f() return 1,2 end; return if x then f() else z, f()

That also deceptively looks like a "postfix if" [2] as in Perl (i.e.
"f() if x" means "if (x) { f() }").  It's doable though.

[1] http://lua-users.org/wiki/TernaryOperator
[2] http://lua-users.org/wiki/MetaLuaRecipes

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Miles Bader-2
In reply to this post by Roberto Ierusalimschy
Roberto Ierusalimschy <[hidden email]> writes:
> 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.

Actually my main complaint about using "end" in an expression-if
construct would be that it's misleading -- "end" sort of means "end of a
sequential list of things", whereas the proposed construct wouldn't have
a list of things at all, just a single thing.  So "end" is both
unnecessary and misleading.

-miles

--
Non-combatant, n. A dead Quaker.

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Alexander Gladysh
In reply to this post by Roberto Ierusalimschy
On Sat, Sep 11, 2010 at 01:01, Roberto Ierusalimschy
<[hidden email]> wrote:
>> On Fri, Sep 10, 2010 at 2:42 AM, David Kastrup <[hidden email]> wrote:
>> > Do you really think you can keep children from growing up?

>> Can you be less cryptic please, and explain what you think the
>> long-term issues are? I think this is a useful addition too.

> 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".

I second this.

> On the other hand, a syntax with "end" is cumbersome.

Do we *really* need a ternary operator in Lua?

Alexander.

Reply | Threaded
Open this post in threaded view
|

Re: Ternary operator patch

Duncan Cross
On Sat, Sep 11, 2010 at 7:18 AM, Alexander Gladysh <[hidden email]> wrote:
> Do we *really* need a ternary operator in Lua?

Well, there are already plenty of things already in the language that
we don't *really* need:
- a:b()
- repeat <x> until y
- Multiple return values
- The operators <, <= and ~=

...and so on. If we didn't have these we could always find ways to
work around them. But the workarounds would have pitfalls, just as "a
and b or c" does, and would make Lua code that bit less pleasant to
write. As simple and slender as Lua is, it is not aggressively so, to
the point that absolutely nothing nonessential is allowed in.

-Duncan

1234 ... 7