Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove ternary operator #1698

Closed
brson opened this issue Jan 28, 2012 · 30 comments
Closed

Remove ternary operator #1698

brson opened this issue Jan 28, 2012 · 30 comments
Labels
A-frontend Area: Compiler frontend (errors, parsing and HIR) E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.

Comments

@brson
Copy link
Contributor

brson commented Jan 28, 2012

One of the comments that stuck with me after the 0.1 announcement was somebody asking why we have a ternary operator, since it is functionally the same as our if expressions. I'm sympathetic to this sentiment

Lately I have been feeling wary about the rapid addition of features to the language and think that we should be more cautious about committing to things we don't really need. One of the original mandates upon the announcement of Rust was to focus on removing features (it's in the language FAQ), and I don't think there's any way to argue that we have succeeded at that.

Admittedly, the ternary operator is a low-maintenance feature, but its removal is also low-impact.

@catamorphism
Copy link
Contributor

I agree. I was wondering why we had the ternary operator, too.

@BrendanEich
Copy link

Agreed. Wish I had made JS an expression language. The great statement/expression split motivates ?: but Rust is free of that, and if-else suffices.

/be

@kevina
Copy link
Contributor

kevina commented Jan 29, 2012

As a very heavy user of the ?: operator in C/C++ I prefer the compact syntax. I also think it formats better when the expression is too long to fit on a single line:

let x = some_very_long_condational
     ? if_true
     : if_false

let x = if some_very_long_condational 
     { if_true}
     else { if_false}

The syntax can get worse, in my view, if if_true and if_false won't fit on a single line. For example, where should the braces be placed.

Just my two cents.

@ssylvan
Copy link

ssylvan commented Jan 29, 2012

I like:

let x = if some_very_long_condational { 
                 if_true
           } else { 
                 if_false
           }

It adds some extra lines (the "else line" and the final bracket), but it keeps it clean and you can add as much code as you want in either.

I use the ternary operator a lot in C++, but I think the syntax is poor. You ave to spot the ? and : in the middle of a sea of other tokens to see that it's even a conditional. With expression-if you have the leading token indicating to the reader "here comes a conditional".

@kevina
Copy link
Contributor

kevina commented Jan 29, 2012

Well I still prefer the syntax of the ?: operator. I find your choice of formatting too verbose, especially for the simple cases when if_true and if_false are a single expressions (as oppose to multiple statements ending in an expression).

Nevertheless, I won't object very strongly if the ?: operator is removed.

@marijnh
Copy link
Contributor

marijnh commented Jan 29, 2012

I'm also using ?: all over the place, but I still think removing it would be a good idea -- it frees up two (!) ASCII sigils in our expression syntax. Think of all the other awesomely cryptic things we could do with them.

@kud1ing
Copy link

kud1ing commented Jan 29, 2012

A non-cryptic use would be to allow them as part of the predicate name.
E.g. "empty?()" instead of "is_empty()".

@nikomatsakis
Copy link
Contributor

@marijnh ++ :)

@graydon
Copy link
Contributor

graydon commented Jan 30, 2012

Personally I don't give a hoot. Igor argued for ternary back in https://mail.mozilla.org/pipermail/rust-dev/2010-November/000110.html

@marijnh
Copy link
Contributor

marijnh commented Jan 31, 2012

This was done in pull req #1705.

@marijnh marijnh closed this as completed Jan 31, 2012
@caitp
Copy link

caitp commented May 1, 2014

    return parent.index_of(child_a) < offset_b ? -1 : 1

looks infinitely better than

    return if parent.index_of(child_a) < offset_b {
        -1 
    } else {
        1
    }

If we have to be pythony about this,

return -1 if parent.index_of(child_a) < offset_b else 1

would be much better.

@rkyoku
Copy link

rkyoku commented Oct 10, 2015

I agree, I don't get it why it had to be removed... Please do not force Rust users to write unnecessarily heavy/verbose code, when such a common practice (ternary operator) exists in most if not all languages.

Anyway, it is done, but I just wanted to add my voice to those supporting a cleaner code style.

@singpolyma
Copy link

I also miss this syntax

@loveencounterflow
Copy link

I think there are three conspiring effects at work here, viz

  1. "The great statement/expression split" (@BrendanEich);
  2. Coercion of non-Booleans in Boolean contexts;
  3. Even 'dynamic' languages don't commonly get 'dynamic syntax' (real macros) and 'dynamic semantics' (a la Python's from __future__ import division) these days.

(1) means that if ... then ... else ... is sth fundamentally different from ... ? ... : ..., which is an entirely dispensable distinction. There are edge cases like return, but overall the distinction is not needed.

(2) means that you can, in many languages, use arbitrary expressions as tests; this looks only convenient as long as you're still using your first language and gets annoying as soon as you start with your second. As pointed out above on this reddit discussion, it's not clear why an empty list should denote either false or true—just write if ( d.length == 0 ) ... and you gained so much clarity!

(3) means you're stuck with whatever the language committee gives you, and whatever that is, the language will likely be stuck with it until someone comes along, forks or rewrites the codebase and gives it a new name. It could be different; there could be languages that allow, say, use 'ternary conditions'; use 'empty lists are false';. There are precedents for that. Of course, a lot of things speak against such flexibility because you will always have to keep in mind those "deviation markers" and remember to copy them when you copy-and-paste program. OTOH if mere users could change language syntax and semantics easily and prepackage such practices into installable modules, that could greatly help in the evolution of the language.

@k-rush
Copy link

k-rush commented Oct 23, 2015

@kevina Sometimes verbosity isn't a bad thing, but I agree that ternary operators clean up code very nicely.

@drbawb
Copy link

drbawb commented Oct 23, 2015

@caitp: what exactly is wrong with?

return if parent.index_of(child_a) < offset_b { -1 } else { 1 }

or one of my personal favorites "hugging clauses"

return 
    if parent.index_of(child_a) < offset_b { -1 } 
    else                                   {  1 }

... or use a match, especially if there's multiple conditions ...

return match parent.index_of(child_a) < offset_by {
  true  => -1,
  false => 1
}

... and of course if it's likely to be reused: just move it into a function ...

return parent.is_child_before(offset_b)

Look at that... you have options... because everything is an expression.

Never in rust have I wanted to save the six characters it takes to write if {} else {} instead of
() ? :, plus chaining additional conditionals looks much nicer with if-as-an-expression. (Nested ternary operators become messy very quickly.)

In my opinion: when using if-as-an-expression I don't see the need to inject so much unnecessary whitespace. I also find it reads more naturally than the ternary operator, and the additional verbosity helps to separate the two clauses visually. That's just my $0.02

@caitp
Copy link

caitp commented Oct 23, 2015

I think you may have misread what I said (and note that this was some time ago)

@drbawb
Copy link

drbawb commented Oct 23, 2015

I'm merely pointing out I don't see how the ternary operator in any way looks "infinitely better."
In my opinion common forms are infinitely more beautiful than special case forms.

@caitp
Copy link

caitp commented Oct 23, 2015

The comment is saying that sometimes, conditionals-as-expressions are very useful, as opposed to conditional statements. Dropping the hugging braces is only subjectively an improvement

@mitchmindtree
Copy link
Contributor

return parent.index_of(child_a) < offset_b ? -1 : 1

vs

return if parent.index_of(child_a) < offset_b { -1 } else { 1 }

@caitp is the second here really infinitely worse than the first? Rust's if else is still an expression (not a statement).

My thoughts are:

  • The second seems like it would be more readable to someone without a history of other languages and
  • We would probably be better off keeping the ? syntax up our sleeves for future sugar (perhaps related to Option, etc)

@loveencounterflow
Copy link

@mitchmindtree totally.

@caitp
Copy link

caitp commented Oct 23, 2015

Again, you're misunderstanding what the comment was saying.

return if parent.index_of(child_a) < offset_b { -1 } else { 1 } is still evaluating the conditional as an expression (and is thus able to be an operand for return).

The braces are ugly, but the main point is about conditional expressions, not about braces. It's about being able to write return foo.bar.baz(<conditional operand>) versus if (<conditional operand>) { return foo.bar.baz(1); } else { return foo.bar.baz(2); }

@retep998
Copy link
Member

I think what we really need to realize is that this issue is over three years old. Considering people haven't really missed ternaries that much in three years, I think it is safe to say that they will stay removed.

@mitchmindtree
Copy link
Contributor

@caitp hmm I'm still not sure i'm following. Are you talking about rust in particular? Or just statements vs expressions in general?

In rust you can still do

return foo.bar.baz(if cond { 42 } else { 0 })

? (I'm aware you weren't talking about braces btw, sorry for the confusion 😸 )

@caitp
Copy link

caitp commented Oct 23, 2015

At the time, in ToT, there was no way to do this in Rust.

@kevina
Copy link
Contributor

kevina commented Oct 24, 2015

I don't have a strong opinion, but I just want to add that if ? and : can better be used for other things, why not use something like ?? and ?: instead, for example cond ?? 43 ?: 0?

@rkyoku
Copy link

rkyoku commented Oct 24, 2015

Why change the way developers have been used to for dozens of years?

Le sam. 24 oct. 2015 02:46, Kevin Atkinson notifications@github.com a
écrit :

I don't have a strong opinion, but I just want to add that is ? and : can
better be used for other thanking why not use something like ?? and ?:
instead. so maybe cond ?? 43 ?: 0.


Reply to this email directly or view it on GitHub
#1698 (comment).

@kevina
Copy link
Contributor

kevina commented Oct 24, 2015

@RenaudParis Sorry, what I meant to say was: I don't have a strong opinion, but I just want to add that if ? and : can better be used for other things, why not use something like ?? and ?: instead, for example cond ?? 43 ?: 0?

One of the reasons the ternary operator was removed was so that "?" could be used for something else in the future. My suggestion was to use another operator. cond ?? 43 ?: 0 is still shorter than if cond {43} else {0}.

@bklooste
Copy link

bklooste commented Nov 9, 2015

I think its correct to be removed however It would not be so bad if bracers were not required for single expression. ( And yes i know how much of a pain this is in the parser it is imho well worth it - readability is very important )

eg

if i ==0 
     return i
else 
      1  

or even

if i == 0  return i
    else 1  

This format is better than

 if i == 0   ? return i
      : 1  

or

if i == 0   
      ? return i 
      : 1  

verses

if i ==0 {
      return i
}
else {
    1
}      

pretty ugly / hard to read for something so common .

It gets worse but easier to read if you have a dev policy against Egyptian braces.

if i ==0
{
     return i
}
else
{
     1
 }      

@Nithin1506200
Copy link

For crab's sake. Bring this feature back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-frontend Area: Compiler frontend (errors, parsing and HIR) E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.
Projects
None yet
Development

No branches or pull requests