Groovy Elvis Operator ?:

In a previous post, I discussed the Nullish coalescing operator in JavaScript. On a related note, I thought of writing about the Elvis operator (?.) of Groovy.

A good starting point would be the ternary operator. The ternary operator takes the form of <expression>? <true return expression> : <false return expression>.

def input = null
def value = input ? input : 0
println value

In this case, we want to check if the variable input contains a value. If not, we want to assume a default value. When we use the ternary operator for this purpose, we end up with a duplicate representation of knowledge because the expression we want to evaluate and the expression we want to return if it turns out to be truthy are the same. In this case, it is input. This duplicate representation is evident in the above code as the variable is repeated before and after the '?'.

Groovy introduced this Elvis operator in version 1.5. Let's put the Elvis operator to use.

def input = null
def value = input ?: 0
println value

While we have removed the duplicate representation, to some, this might not seem like a benefit worth creating an operator. Let us take another example to illustrate the second benefit, which might not be obvious.

def person = new Person();
def name = person.name ? person.name : ""
println name

Here, in addition to duplicate representation, there is a runtime overhead of evaluating the same expression twice. Let's refactor this code to use the Elvis operator.

def person = new Person();
def name = person.name ?: ""
println name

Note that here, Groovy ensures that the expression is evaluated only once. Let's make the following changes to confirm that the expression is evaluated only once.

class Person{
    String name
    
    String getName(){
     println "getName called"
     return name
    }
}

def person = new Person(name: 'Naresha');
def name = person.name ?: ""
println name

You will see that the message "getName called" gets printed only once.

Now, let's compare this with the JavaScript. Since JavaScript had the logical OR operator ||, which could achieve the same result as the Elvis operator, JavaScript didn't need a separate Elvis operator. Note that the ternary and logical OR operators were available from ECMAScript version 1.

JavaScript has this complexity of null and undefined. Hence, the nullish coalesce operator makes sense there. While in Groovy, we only have null. Therefore, if we want to check for null value instead of the boolean coerced value, we could explicitly use the expression input != null for example.

Since the purpose of the Elvis operator is mostly to assign a default value, Groovy, in its version 3, introduced the Elvis assignment operator.

class Person{
    String name
}

def person = new Person();
person.name ?= 'NA'
println person.name

As our intention in this example is to replace invalid or absence of values with corresponding default values instead of assigning the value to another variable altogether, the Elvis assignment operator comes in handy here.

As far as the origin of the Elvis operator is concerned, it looks like it first appeared in C and C++ around 2001 by making the expression after the question mark in the ternary operator optional. It didn't have a distinct name at that time, though.

In 2007, Groovy used ?: as a distinct operator named Elvis. Since then, this operator has been used in other languages, such as PHP, Kotlin, etc.