20

One of the proposed features for Java 7's "Project Coin" was the "Elvis operator". A report of a 2009 JavaOne presentation on Project Coin described it as such:

One of the "small features" covered in this presentation is the so-called "Elvis operator," a more concise version of the ternary operator. I find myself missing some of the features of Groovy when using traditional Java and this would be one operator that I could use in both languages if it was added. The "Elvis" operator is handy for specifying a default value that can be used when the evaluated expression is null. Like Groovy's safe navigation operator, it is a concise way to specify how to avoid unnecessary nulls. I have blogged previously about how I like to avoid the NullPointerException.

While other aspects of Project Coin were ultimately implemented, this one was not. Why was the Elvis Operator ultimately rejected, despite being presented at JavaOne as a likely candidate for inclusion?

To be clear, I'm specifically asking about this operator and the reason it was rejected as part of Java 7's "Project Coin", given that it was seriously considered then. I suspect that there are mailing lists or such where the reasons for rejecting it were discussed, but I couldn't find anything. If there is more general information about why it is not included in any version of Java, that is acceptable but not preferred.

10
  • 4
    suspicious minds?
    – Ewan
    Commented Oct 19, 2017 at 16:05
  • 2
    Mot likely because it supports and encourages the use of nulls as legitimate values, and more fundamentally is counter to OO principles because you check the type of an object before executing a method.
    – JacquesB
    Commented Oct 19, 2017 at 17:00
  • Unless someone is going to dig up explicit documents (emails, memos, transcripts) of the decision process or was a direct participant of the decision, we can't really know the answer here. E.g. Robert's answer is just speculation and general language design considerations, not a factual and specific reason for the rejection of this operator. I am therefore voting to close this question as opinion-based.
    – amon
    Commented Oct 20, 2017 at 9:24
  • 1
    @amon: I freely admitted that my answer was speculation at the beginning of my post. However, I posted an answer anyway because 1. I'm teaching how to fish instead of giving a fish, and 2. This post can be used as a target for close dupes, if we play our cards right. The idea behind an answer providing a general analysis is to discourage endless arguments about minute language decisions and help others see a broader view of the overall issues. Commented Oct 20, 2017 at 13:14
  • @RobertHarvey A “Why does language X not have feature Y” canonical dupe target would be convenient, but the question in its current form does not seem suitable for that. If it were to be edited to ask this general question (using X=Java/Y=?. as an example) it would certainly be too broad as an ordinary question, but you would have a good answer.
    – amon
    Commented Oct 20, 2017 at 13:49

1 Answer 1

22

Naturally, the best person to ask this question is someone on the JCP Executive Committee, not us. However, that won't prevent me from engaging in some idle speculation.

The answer to every "why wasn't this feature implemented" question is always because the benefits did not exceed the costs.

Eric Lippert (former member of the C# team) says that, in order for a product to have a feature, that feature must be:

  • thought of in the first place
  • desired
  • designed
  • specified
  • implemented
  • tested
  • documented
  • shipped to customers

In other words, there must be many important things that must happen before any new programming language feature can be realized. The costs are larger than you think they are.

On the C# team, every new feature request starts out with a score of minus 100. Then the team evaluates the benefits and the costs, adding points for the benefits, and subtracting points for the costs. If the score doesn't go above zero, the proposed feature is summarily discarded. In other words, the new feature must provide a compelling benefit.

But the Elvis Operator made it into C#. So why didn't it make it into Java?

Despite their apparent similarities, Java and C# have significantly different language philosophies. This is evidenced by the fact that Java enterprise programs tend to be large, structural collections of architecture. Brevity and language expressiveness are sacrificed on the altar of ceremony and ease of coding. Well-known software architectural patterns that everyone on the development team can recognize are preferred over language conveniences.

Consider this Reddit exchange:

The Elvis operator has been proposed for every version of Java since 7, and has been rejected every time. Different languages fall on different points along the spectrum from "pure" to "pragmatic", and languages implementing the Elvis operator do tend to be further toward the pragmatic end of the spectrum than Java.

If you have a team of 15+ year Java pros writing a highly-distributed, highly-concurrent backend processing system of some sort, then you probably want a great degree of architectural rigor.

However, if you have a junior to mid-level team, half of whom migrated from Visual Basic, and you have them writing an ASP.NET web app that mostly just does CRUD operations... then it might be overkill to design a bunch of AbstractFactoryFactory classes to abstract away the fact that you have no control over which columns are nullable in the shitty legacy database that you must use.

These profound differences in language philosophy extend not only to the way the languages are used, but to the way the language design process itself is undertaken. C# is a benevolent dictator language. To get a new feature into C#, you only really have to convince one person: Anders Hejlsberg.

Java takes a more conservative approach. To get a new feature into Java, it must get consensus from a consortium of large vendors such as Oracle, IBM, HP, Fujitsu & Red Hat. Obviously, that process is going to be slower and present a higher bar for new language features.

The question "why wasn't x feature implemented..." always implicitly includes the words, "...if it's obviously such a good idea?" As I have adequately demonstrated here, the choice is never that simple.

13
  • 14
    sarcasm: Because AbstractFactoryFactory classes are a nice indicator of architectural rigor, and not code bloating. /sarcasm.
    – Machado
    Commented Oct 19, 2017 at 17:22
  • 3
    @RobertHarvey Your conclusions about the role of committees in the design of the Java language are way too simplistic. While there is indeed collaboration with the community and with industry partners, the statement that the Java language is "design by committee" is pretty much completely incorrect, and a terrible (though sadly, superficially believable) explanation for this poster's question. Commented Oct 20, 2017 at 15:19
  • 7
    Most of the earlier reasons you listed -- every language feature is bigger than anyone thinks, finite budgets (for effort, for change, for complexity) -- are accurate. And I'd add: we don't do feature X because we think that other features Y and Z are better choices. Further, we also take a more conservative approach than other languages, because we know each feature interacts with, or in some cases forecloses on, other possible features in the future. We want Java to remain vibrant and relevant in 20 years, which necessarily means not cramming in every feature that might seem cool now. Commented Oct 20, 2017 at 16:46
  • 2
    "Java enterprise programs tend to be large, structural collections of architecture" -- this is an excellent euphemism. I may reuse this next time I see a steaming pile. Commented Oct 20, 2017 at 23:01
  • 2
    @FrankHileman Delegates are a really bad example to argue your case because they are an atrocious and confusing language feature. I've never missed them in other languages. Later both C# and Java got lambdas (and Java also got method reference syntax) which represent a saner solution to the same problem space. Callbacks prior to Java 8 were painfully verbose, but the solution found by Java (the “functional interface” concept) allowed lambdas to be used without requiring API changes! Say what you want about the language, but that was an impressively well-done language evolution.
    – amon
    Commented Oct 27, 2017 at 14:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.