Elvis operator
In certain computer programming languages, the Elvis operator, often written ?:, is a binary operator that evaluates its first operand and returns it if its value is logically true (according to a language-dependent convention, in other words, a truthy value), and otherwise evaluates and returns its second operand. The second operand is only evaluated if it is to be returned (short-circuit evaluation). The notation of the Elvis operator was inspired by the ternary conditional operator, ? :, since the Elvis operator expression A ?: B is approximately equivalent to the ternary conditional expression A ? A : B.
The name "Elvis operator" derives from the resemblance of the notation ?:, when viewed sideways, to an emoticon of Elvis Presley with his signature hairstyle.[1]
A similar operator is the null coalescing operator, where the boolean truth(iness) check is replaced with a check for non-null instead. This is usually written ??, and can be seen in languages like C#[2] or Dart.[3]
Alternative syntaxes
[edit | edit source]In several languages, such as Common Lisp, Clojure, Lua, Object Pascal, Perl, Python, Ruby, and JavaScript, there is no need for the Elvis operator, because the language's logical disjunction operator (typically || or or) is short-circuiting and returns its first operand if it would evaluate to a truthy value, and otherwise its second operand, which may be a truthy or falsy value (rather than a Boolean true or false value, such as in C and C++). These semantics are identical to the Elvis operator.
Example
[edit | edit source]Boolean variant
[edit | edit source]In a language that supports the Elvis operator, something like this:
x = f() ?: g()
will set x equal to the result of f() if that result is truthy, and to the result of g() otherwise.
It is equivalent to this example, using the conditional ternary operator:
x = f() ? f() : g()
except that it does not evaluate f() twice if it yields truthy. Note the possibility of arbitrary behaviour if f() is not a state-independent function that always returns the same result.
Object reference variant
[edit | edit source]This code will result in a reference to an object that is guaranteed to not be null. Function f() returns an object reference instead of a boolean, and may return null, which is universally regarded as falsy:
x = f() ?: "default value"
Languages supporting the Elvis operator
[edit | edit source]- In GNU C and C++ (that is: in C and C++ with GCC extensions), the second operand of the ternary operator is optional.[4] This has been the case since at least GCC 2.95.3 (March 2001), and seems to be the original Elvis operator.[5]
- In Apache Groovy, the "Elvis operator"
?:is documented as a distinct operator;[6] this feature was added in Groovy 1.5[7] (December 2007). Groovy, unlike GNU C and PHP, does not simply allow the second operand of ternary?:to be omitted; rather, binary?:must be written as a single operator, with no whitespace in between. - In PHP, it is possible to leave out the middle part of the ternary operator since PHP 5.3.[8] (June 2009).
- The Fantom programming language has the
?:binary operator that compares its first operand withnull. - In Kotlin, the Elvis operator returns its left-hand side if it is not null, and its right-hand side otherwise.[9] A common pattern is to use it with
return, like this:val foo = bar() ?: return - In Gosu, the
?:operator returns the right operand if the left is null as well. - In C#, the null-conditional operator,
?.is referred to as the "Elvis operator",[10] but it does not perform the same function. Instead, the null-coalescing operator??does. - In ColdFusion and CFML, the Elvis operator was introduced using the
?:syntax. - The Xtend programming language has an Elvis operator.[11]
- In Google's Closure Templates, the Elvis operator is a null coalescing operator, equivalent to
isNonnull($a) ? $a : $b.[12] - In Ballerina, the Elvis operator
L ?: Rreturns the value ofLif it's not nil. Otherwise, return the value ofR.[13] - In JavaScript, the nullish coalescing (
??) operator is a logical operator that returns its right-hand side operand when its left-hand side operand isnullorundefined, and otherwise returns its left-hand side operand.[14] - In Perl there is a logical short-circuiting disjunction
||and a similar lower precedenceor.[15] They differ from the bitwise or operator|which evaluates both operands without short-circuiting. There is also a corresponding assignment operator||=that evaluates its right-hand operand and assigns it to the left-operand unless the logical value of the left-operand is true. There is also a short-circuiting defined-or operator//which evaluates its right-operand and returns its value only if the left-operand is undefined. Finally, the corresponding assignment operator is//=. Similar exclusive-or operators are not Elvis operators as they do not short-circuit. Other short-circuiting operators are the logical-and ones&&andand, but their behavior is opposite that of the Elvis operator.
See also
[edit | edit source]?:or conditional operator, when used as a ternary operator- Null coalescing operator,
??operator - Safe navigation operator, often
?. - Spaceship operator
<=> - Option type
References
[edit | edit source]- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
- ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).