Java
Article
By Nicolai Parlog

How Project Amber Will Revolutionize Java

By Nicolai Parlog

This is the editorial for the SitePoint Java Channel newsletter that we send out every other Friday. Subscribe here!

Earlier this week Brian Goetz, Java Language Architect at Oracle, officially announced Project Amber and I could not be more excited about it! It will continue what Java 8 began and make Java a much less verbose and even more fun language. Type inference, massively simplified data classes, pattern matching, … all of this has been bubbling up in recent months but it is great to see it put on official tracks.

(While this might be new to Java, non-Java devs might scoff and look down on us with comments like, “we’ve been using that for ten years, now.” Well, good for you but no reason to rain on our parade so stfu!)

Revolutionary Fighters

I’m sure you can’t wait to see those improvements I promised, so let’s do that first. Once we’ve explored them I will spend a few words on Project Amber and release date speculations.

(If you’re interested to see how these proposals and value types might play together, have a look at What Future Java Might Look Like).

Local Variable Type Inference

Java has done type inference since Java 5 (for type witnesses in generic methods) and the mechanism was extended in Java 7 (diamond operator), 8 (lambda parameter types), and 9 (diamond on anonymous classes). Under Project Amber it is planned to be extended to type declarations of local (!) variables:

// now
URL url = new URL("...")
URLConnectoin conn = url.openConnection();
Reader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

// maybe in the future
var url = new URL("...")
var conn = url.openConnection();
var reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

Here, the types of url, conn, and reader are perfectly obvious. As a consequence the compiler can infer them, making it unnecessary for us to specify them.

Note that type inference is not dynamic typing – it’s still strong typing just with less typing (Brian’s pun, presumably intended). The type information will still end up in the bytecode and IDEs will also be able to show them – it’s just that we don’t have to write it out anymore.

For more information, have a look at JEP 286.

Enhanced Enums

As it stands, enums can not be generic, meaning you can not give individual enum instances fields of specific types:

// now
public enum FavoriteNumber {

    INTEGER(42),
    FLOAT(3.14);

    // wouldn't it be nice if this were more specific than Number?
    public final Number favorite;

    FavoriteNumber(Number favorite) {
        this.favorite = favorite;
    }

}

Project Amber considers to let enums have type parameters:

// maybe in the future
public class FavoriteNumber<T extends Number> {

    INTEGER<Interger>(42),
    FLOAT<Float>(3.14);

    // wouldn't it be nice if this were more specific than Number?
    public final T favorite;

    FavoriteNumber(T favorite) {
        this.favorite = favorite;
    }

}

And the great thing is, the compiler will perform sharp type checking and know which generic types a specific enum instance has:

// maybe in the future
float favorite = FavoriteNumber.FLOAT.favorite;

For more information, have a look at JEP 301.

Lambda Leftovers

Great name, eh? These are a couple of smaller improvements to lambda expressions and method references. The first is that the compiler will be better at picking the target for a lambda expression or method reference in situations where it has to pick one of several overloads:

// now; compile error: "ambiguous method call"
method(s -> false)

private void method(Predicate<String> p) { /* ... */ }
private void method(Function<String, String> f) { /* ... */ }

It is weird that the compiler thinks this is ambiguous because to us it very much isn’t. When lambda leftovers are implemented, the compiler agrees.

Java 8 deprecated _ as variable name and disallowed it as a lambda parameter name. Java 9 will disallow using it as variable names as well so it is free to get a special meaning, namely to mark unused lambda parameters (yes, more than one in the same expression):

// maybe in the future

// ignore the parameter marked as `_`
BiFunction<Integer, String, String> f3 = (i, _) -> String.valueOf(i);

// if there were a TriFunction:
BiFunction<Integer, String, String, String> f3 = (i, _, _) -> String.valueOf(i);

Finally, Project Amber explores the possibility to let lambda parameters shadow variables in the enclosing scope. This would make naming them a little easier because as it stands it can be a little onerous:

private Map<String, Integer> wordLengthCache;

// now
public int computeLength(String word) {
    // can't reuse `word` in lambda, so... maybe `w`?
    wordLengthCache.computeIfAbsent(word, w -> w.length());
}

// maybe in the future
public int computeLength(String word) {
    // can't reuse `word` in lambda, so... maybe `w`?
    wordLengthCache.computeIfAbsent(word, word -> word.length());
}

For more information, have a look at JEP 302.

Data Classes

We’ve all created plenty of simple data holder classes that needed dozens of lines of code for fields, constructor, accessors, equals, hashCode, toString. While IDEs happily generate all of that, making typing it unnecessary even today, it is still code that needs to be understood (does the constructor do any validation?) and maintained (better not forget to add that new field to equals).

In an aggressive move to reduce boilerplate, the compiler might generate all of that stuff on the fly without us having to bend a finger!

// maybe in the future
public class User(String firstName, String lastName, DateTime birthday) { }

We can get everything else I mentioned above for free and only need to actually implement what’s non-standard (maybe users have an ID that alone determines equality, so we’d want an according equals implementation). Getting rid of all that code would be a great boost for maintainability!

(There is no JEP for this proposal yet but Amber will adopt it as soon as it is.)

Pattern Matching

Java’s current switch statement is pretty weak. You can use it for primitives, enums and strings but that’s it. If you want to do anything more complex, you either resort to ifelseif chains or, if you can’t get the Gang of Four book out of your head, the visitor pattern.

Project Amber explores what is commonly known as pattern matching. It works over all types, can have conditions that are more complex than equality checks, and is an expression, meaning it results in a value that can be assigned. Here’s an example Brian showed at Devoxx Belgium a few months ago:

// maybe in the future
String formatted = switch (constant) {
    case Integer i -> String.format("int %d", i);
    case Byte b: //...
    case Long l: // ...
    // ...
    default: formatted = "unknown"
}

(There is no JEP for this proposal yet but Amber will adopt it as soon as it is.)

Project Amber. Because, why not?

Project Amber

Now that we know which features are currently being explored as part of Project Amber, it is time to take a closer look at the project itself. In the welcome mail it is described is an “incubation ground for selected productivity-oriented Java language JEPs.” Loosely said, its scope is defined as whatever JEP the expert group finds interesting and aligns with the overall mission statement:

To be considered for adoption by Project Amber, a feature should first be described by a JEP. This means that this is not the place for discussing random language feature ideas (the whole rest of the internet is still available for that); let’s keep the focus on the specific features that have been adopted.

Read that mail to get links to JEPs, mailing lists, and the repo.

Release Date

A natural question to have is, when will the project be shipped? When can you start writing that awesome code I keep promising? The most responsible answer is that nobody knows.

Leaving responsibility aside, we can speculate a little. Project Lambda, which brought lambda expressions and streams, took a little more than four years from inception in December 2009 to its debuting release in March 2014. Project Jigsaw, notorious for its delays, started a year earlier, in December 2008, and is only being shipped now, making it take almost nine years. Keep in mind, though, that Oracle bought Sun in 2010 and I can only assume that engineering efforts were adversely affected by the transition. Also, it seems to me that both projects are considerably more complex and monolithic than Amber (although both is hard to judge from the outside).

Project Amber is more of a roof for various changes that move the language into a common direction but might not have to be shipped at once to make sense. Under this assumption and guessing the project’s development time based on Lambda and Jigsaw, it seems plausible that some changes will make it into Java 10.

Before you ask: Nobody knows when 10 will be out! Again some speculation, back in 2012 Mark Reinhold, Chief Architect of the Java Platform Group, proposed a two-year release cycle that due to delays became more of a three-year cycle. Extrapolating the future from two data points (luckily I am not bound to scientific standards here), 2020 looks like a good guess.

Keep in mind, though, that Project Valhalla started in July 2014 and took on the massive undertaking to implement generic specialization and value types. It is not targeted for any release yet but it looks like it’s in the time frame to go into 10. If so, it could very well delay the release due to its complexity.

So bottom line is: Nobody knows. If I had to bet money I would put it on 2020. Fingers crossed.

About That Name…

Oh yeah, why is it called Project Amber? Because it’s shiny? Because it preserves dead things? I don’t know.

Instead of spending needless cycles thinking about it I opted to ask Brian himself but he was either very secretive or very open:

He made a proposal, though, that we come up with an explanation, so why not?

So here’s the deal: You leave a comment or tweet (don’t forget to mention me) with your explanation why it might be called Project Amber and I will let Brian and his team choose the one they like best (deadline: March 26th). To make this a real competition, the winner gets a copy of my upcoming book about the Java 9 module system.

So what do you think? Why Amber?

Two weeks later…

Submissions

Thank you everybody for your participation. Your ideas:

Every time people mention “Amber” I remember this part of Jurasic Park haha, maybe all this new features are coming from the DNA of old programmers but with fresh ideas. (Juan Moreno)

Project Coin -> Milling project coin -> While we’ve got our hands rummaging around in the treasure chest we also happen to find a semi precious stone -> Amber (Andreas Aronsson)

Amber simply contains all that we wanted for that project:
First astonishment to catch your interest,
then momentum to keep you going,
brilliance shining everywhere,
encouraging you not only to evolute
but to revolutionize your code.
(matameko)

We didn’t want Java to become fossilized, but we also want the features we’re adding to make the language dazzle again! (Jim Bethancourt)

I guess they just had name contest and there’s no logic behind it. Nice. Shiny. Short. No problems with other cultures and languages. (Jukka Nikki)

It could be also name of daughter of project lead. (Jukka Nikki)

And The Winner is…

Kwakeroni (hand-picked by Brian Goetz himself) with:

Congratulations! 😀 On your great detective skills as well as the price. While the explanation is definitely intriguing, Brian has another one:

So now we know why the project revolutionizing Java is called Amber….

  • Jukka Nikki

    Amber: I guess they just had name contest and there’s no logic behind it. Nice. Shiny. Short. No problems with other cultures and languages.

    • That’s kind of a non-explanation but I will hand it in. Who knows? :)

      • Jukka Nikki

        It could be also name of daughter of project lead. Good name, anyway.

    • P.K. Hunter

      Will be a hassle to explain all the time as being different from Ember, which is also “Java”script.

  • Norbert Kiesel

    Should this not at least mention Kotlin and Swift which have something very similar already implemented?

    • It does:

      Non-Java devs might scoff and look down on us with comments like, “we’ve been using that for ten years, now.”

      Beyond that, I saw no reason to list every language that already has one or more of these features.

  • Andreas Aronsson

    Project Coin -> Milling project coin -> *While we’ve got our hands rummaging around in the treasure chest we also happen to find a semi precious stone* -> Amber

  • Andreas Aronsson

    Regardiing the when: I would like to speculate that by fixing overall code quality and improving their build system significantly in the recent years the velocity have been increased.

  • Jim Bethancourt

    We didn’t want Java to become fossilized, but we also want the features we’re adding to make the language dazzle again!

  • Marcin Moskala

    Just use Kotlin xP

  • matameko

    Amber simply contains all that we wanted for that project:
    First *a*stonishment to catch your interest,
    then *m*omentum to keep you going,
    *b*rilliance shining everywhere,
    encouraging you not only to *evolute*
    but to *r*evolutionize your code.

  • Bill

    Import alias is a cool feature to have

  • Jonathan Fisher

    This isn’t a slam against the people who are putting forth the effort to improve the already great Java language, but the local type inference is a feature I’d rather not have. It’s one of the more ridiculous proposals I’ve seen. Whenever you have “more than one equally correct way” to do things, you only create confusion. Can we please work on more important features instead? I’d be very happy to not see this [anti-]feature make it to the relase.

Recommended
Sponsors
Get the latest in Java, once a week, for free.