2
$\begingroup$

From Wikipedia:

In certain computer programming languages, the Elvis operator, often written ?:, is a binary operator that returns its first operand if that operand evaluates to a true value, and otherwise evaluates and returns its second operand.

For example in Kotlin, foo ?: bar will yield foo if foo is not null, and bar if otherwise.

Seeing how few languages support this, made me wonder: why don't more languages adopt this operator? AFAIK, short-circuit or || yields the same for some languages, but in C for example, the result of || will always be a boolean, so it won't work. Also, the Elvis operator looks more concise than short-circuit or || and the ternary counterpart: A ? A : B.

So why is it not more common?

$\endgroup$
5
  • 6
    $\begingroup$ A null-coalescing operator is rather common ime, it just tends to look different — Swift, JS, and C# all use ?? for that. $\endgroup$
    – Bbrk24
    May 17, 2023 at 15:12
  • $\begingroup$ @Bbrk24 null-coalescing is a little bit different AFAIK? The Boolean check is now check for non-null. $\endgroup$ May 17, 2023 at 15:18
  • $\begingroup$ Your Kotlin example is a null-coalescing operator, it just happens to look the same as gcc’s Elvis. $\endgroup$
    – Bbrk24
    May 17, 2023 at 15:20
  • $\begingroup$ @Bbrk24 all right, it’s my sleep time now so tomorrow I’ll find a better example $\endgroup$ May 17, 2023 at 15:21
  • $\begingroup$ Many C compilers (GCC and Clang at least) actually add this as an extension. Basically, they let you skip the middle expression in a ternary if, returning the left one if it evaluates to true $\endgroup$
    – abel1502
    May 17, 2023 at 17:26

3 Answers 3

10
$\begingroup$

Many popular mainstream languages that focus at least somewhat on conciseness have a similar operator, so I'd say that it is fairly common.

First, some notes:

  1. For the purposes of this answer, it doesn't matter whether the syntax is ?:, ??, || or or, especially since all are equally concise.
  2. What is a "true value" for this operator differs from language to language, and may not be the same as what is considered a "true value" in other contexts (like in an if condition).

Now, let's go though some languages and see what we find:

  • C and C++: no Elvis in the standards, since concise syntax sugar does not seem to be focus for these languages
  • Java: Elvis was explicitly rejected, seemingly also because syntax sugar is not a focus for Java.
  • C#: ?? is a null-checking Elvis
  • Python: or works as truthy-checking Elvis
  • JavaScript: || works as an Elvis operator that checks for truthiness, ?? is an Elvis operator that only checks for null and undefined
  • PHP: ?: is a truthy-checking Elvis, ?? is a null-checking Elvis
  • Ruby: || works as a truthy-checking Elvis
  • Go: no Elvis, since Go prefers simplicity of language to conciseness of code
  • Swift: ?? is a nil-checking Elvis
  • Rust: no Elvis, presumably because Rust does not have concepts similar to truthiness or null
$\endgroup$
1
  • $\begingroup$ It's worth noting Rust has .or(...) for Options, which acts a bit like Elvis for two Option-wrapped values: play.rust-lang.org/… $\endgroup$ Jul 13, 2023 at 19:26
6
$\begingroup$

Some languages simply don't have (a relevant type of) nulls, or don't have the concept of non-Boolean thruthiness, making it a not applicable feature.

$\endgroup$
2
  • $\begingroup$ It's worth adding that the Elvis operator isn't necessarily just a null-coalescing operator, it often distinguishes "truthy" vs. "falsy" values rather than just non-null or null values. So the operator would be inapplicable if the language lacks both nulls and "truthiness" (i.e. implicit coercion of other types to Booleans). $\endgroup$
    – kaya3
    May 18, 2023 at 4:06
  • $\begingroup$ @kaya3 Thanks. Added. $\endgroup$
    – Adám
    May 18, 2023 at 5:42
2
$\begingroup$

In at least Python, the logical or works in much the same way:

>>> a = None
>>> a or 1
1
>>> a = False
>>> a or 1
1
>>> a = True
>>> a or 1
True
>>> a = "Hello"
>>> a or 1
'Hello'

I suspect more strongly-typed languages would not be okay with all falsey values being coalesced.

$\endgroup$
5
  • 1
    $\begingroup$ Strongly-typed languages typically don't have a concept of "falsy" values in the first place ─ "truthiness" means the result of a coercion to a Boolean, and strong typing generally means few or no coercions. $\endgroup$
    – kaya3
    May 18, 2023 at 4:07
  • 1
    $\begingroup$ @kaya3 yet, interestingly a lot of strongly typed languages do actually allow miixing null with a different type. Let's say in Java the method String foo(String s) { return s.toUpperCase(); } can produce an NPE. Similarly if we go by the signature String bar(); can also lead to an NPE with bar().toUpperCase();. So, even though Java is strongly typed, it does have values that aren't the type you might expect. Which is very close to having concept for "falsy" as most code that consumes String should also account for null. $\endgroup$
    – VLAZ
    May 18, 2023 at 7:57
  • 2
    $\begingroup$ @VLAZ It's related, but "truthiness" particularly is whether a value satisfies a conditional test in e.g. an if statement, while loop, or logical operators. In most strongly-typed languages, there is no such concept because the condition must be an actual Boolean value, not just any other type that can be coerced. $\endgroup$
    – kaya3
    May 18, 2023 at 8:06
  • $\begingroup$ @kaya3-supportthestrike: IMHO, C could have been both more useful and more efficient to process if x && y and x || y were specified as requiring that x and y be of compatible types, and be equivalent to x ? y : x, and x ? x : y , respectively, but with x only being evaluated once. Having the operator coerce the inputs to 0 and 1 creates more work for the compiler while making it necessary for programmers to write code that explicitly uses temporary variables a compiler wouldn't need to bother with (since code would place x wherever the code for the containing expression... $\endgroup$
    – supercat
    Jul 8, 2023 at 18:28
  • $\begingroup$ ...would expect to find it, test its "truthiness", and then either load y in the same place or leave that place holding x). $\endgroup$
    – supercat
    Jul 8, 2023 at 18:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .