The Elvis operator

VividVerism

Ars Praefectus
6,728
Subscriptor
I had to look up what it even is (seems pretty neat actually, I'd definitely use it from time to time). In the process I accidentally looked up the origin too.


Wikipedia said:
The name "Elvis operator" refers to the fact that when its common notation, ?:, is viewed sideways, it resembles an emoticon of Elvis Presley with his signature hairstyle.
 
  • Haha
Reactions: bjn

Lt_Storm

Ars Praefectus
16,294
Subscriptor++
I'm learning Kotlin and ran across the Elvis operator. I understand what it does and that it's in other languages, but this is the first I've heard of it.

How the hell did they come up with the name "Elvis operator"?
Never mind, I'm an idiot, you didn't actually ask how they came up with it, but the name....
 

Apteris

Ars Tribunus Angusticlavius
8,938
Subscriptor
Also, for the Elvis emoticon I think it's missing an o. ?:eek:.... Which, of course, the bbcode reader eats... Sigh.
"icode" should prevent that.

You could also insert a zero-width space in the middle of your sequence of characters to prevent emoticon formation, but I reserve that trick for life-or-death scenarios.
 
Last edited:
  • Like
Reactions: VividVerism

VividVerism

Ars Praefectus
6,728
Subscriptor
Would be useful to mention what it does... I mean, pushing that mouse button is hard work!
Fair enough, lol :)

Wikipedia said:
[T]he Elvis operator expression A ?: B is approximately equivalent to the ternary conditional expression A ? A : B.

I.e. if A is true-like, return A; otherwise return B.
 

iljitsch

Ars Tribunus Angusticlavius
8,474
Subscriptor++
Yeah C had that special in-the-foot-shooting ability way back in the day!

At least with Python you have to add an extra : so := to get the dangerous stuff rather than = (== ?) to get the normal stuff. In C if you forget to type the second = in an if statement you require foot surgery.

I once got seriously bitten by an x++ bug / misfeature in PHP and now no longer use that in any expression that does more than x = x + 1.

I do like these creative operator names, though.
 
  • Like
Reactions: dio82

Haas Bioroid

Ars Scholae Palatinae
1,424
Subscriptor
Yeah C had that special in-the-foot-shooting ability way back in the day!

At least with Python you have to add an extra : so := to get the dangerous stuff rather than = (== ?) to get the normal stuff. In C if you forget to type the second = in an if statement you require foot surgery.

I once got seriously bitten by an x++ bug / misfeature in PHP and now no longer use that in any expression that does more than x = x + 1.

I do like these creative operator names, though.
Hence the famous yoda-condition pattern :

if (<constant> == <variable>) { ... }

So that if you forget a = you'll get an error at compile time.
 

iljitsch

Ars Tribunus Angusticlavius
8,474
Subscriptor++
Oh right, so I should write:

if (10 == a)

rather than:

if (a == 10)

Super counter-intuitive, though.

Edit: I’d say that a compiler should generate the same error for if (a = 10) as if (10 = a), though. There is no reasonable use of

if (<variable> = <constant>)

And when it’s two variables you’re screwed whatever the order.
 

Haas Bioroid

Ars Scholae Palatinae
1,424
Subscriptor
Oh right, so I should write:

if (10 == a)

rather than:

if (a == 10)

Super counter-intuitive, though.

Edit: I’d say that a compiler should generate the same error for if (a = 10) as if (10 = a), though. There is no reasonable use of

if (<variable> = <constant>)

And when it’s two variables you’re screwed whatever the order.
Your concern is sensible. AFAIK, modern C compilers can emit warning in case of assignation in test expression. That's probably to be prefered.
 
  • Like
Reactions: VividVerism

dspariI

Smack-Fu Master, in training
33
Apparently it's frowned upon because of its propensity for adding reading complexity, but Python has the "walrus operator" written as := and used to assign a variable in a statement.

Python:
if func(var):
    print(func(var))
#or:
if new := func(var):
    print(new)
If you read PEP 572, it gives some specific use cases where it results in cleaner code. One of them is reading binary files which is where I have used it.

Is

Python:
while (data := binary_file.read(4)):
    process(data)

hugely different from

Python:
data = binary_file.read(4)
while (data):
    process(data)
    data = binary_file.read(4)
?

No, but it is a bit nicer.
 
  • Like
Reactions: VividVerism

Stern

Ars Praefectus
3,504
Subscriptor++
AFAIK, modern C compilers can emit warning in case of assignation in test expression. That's probably to be prefered.
I think all of the major compilers warn about this by default now. The idiom is that if you really want an assignment, you indicate it by using double parentheses.
 

bjn

Ars Praefectus
3,217
Subscriptor++
In c++, if func returns a value intepretable as bool (eg std::optional<T>), I do like going...

Code:
if(auto x = func())  {
  doSomething(*x);
}

Now what Javascript does with == is a true abomination. So much so they had to invent === to get around it.

I once spent a day debugging some code with a colleague only to find a typo in a C++ if statement caused it all. Something along the lines of...

Code:
if (condition1 && condition2 || !!condition3) {
}

Drove us nuts, we just couldn't see the '!!' typo for ages. I now use the C++ keyword* not instead of '!'. Also 'and' and 'or', makes for nicer looking code IMHO.

*Those are infact keyworks in the language, but people don't use them.
 
  • Like
Reactions: curih

moosemaimer

Ars Scholae Palatinae
717
I only started writing Python recently (programming in general, really) so I don't have years of experience writing walrus-free code to be crotchety about, but there's an undercurrent of people who don't like it. Although I did get bitten recently (those tusks!):

Python:
if data := func() and condition:
    do_thing(data)

# is actually

if data := (func() and condition):
# data is True/False, not func return
# so do:
if (data := func()) and condition:
 
  • Like
Reactions: VividVerism

curih

Ars Praetorian
453
Subscriptor
I now use the C++ keyword* not instead of '!'. Also 'and' and 'or', makes for nicer looking code IMHO.

*Those are infact keyworks in the language, but people don't use them.
I've started doing the same. I was specifically worried about the old & instead of &&, or | instead of ||. Actually got flagged in a code review once because someone didn't know you could use 'and' and 'or' instead of && and ||. The history of those is actually kind of interesting. They're in the language primarily because of the need to support some character sets that didn't have & or | in them.

Edit: Those particular mistakes were worrying for me since I come from the hardware world and used to write a fair bit of Verilog where I would regularly be using both variants.
 
  • Like
Reactions: bjn

dio82

Ars Tribunus Angusticlavius
9,389
Subscriptor
I only started writing Python recently (programming in general, really) so I don't have years of experience writing walrus-free code to be crotchety about, but there's an undercurrent of people who don't like it. Although I did get bitten recently (those tusks!):

Python:
if data := func() and condition:
    do_thing(data)

# is actually

if data := (func() and condition):
# data is True/False, not func return
# so do:
if (data := func()) and condition:
That right there is a damned good reason to never use the walrus. Most of the time I spend reading code, so it should be absolutely clear what it does in detail. When speed reading through code, that difference is subtle enough that I might miss it.