Saturday, February 28, 2009

Small Language Changes for JDK7

For those who haven't been paying attention, there is a new project from Sun to attract proposals for small language changes to JDK7. Even in the first day of open calls for proposals, the entries have been very interesting:
  • Strings in Switch, a proposal from Joe Darcy to be able to use Strings in switch statements.

  • Automated Resource Blocks, a proposal from Josh Bloch to be able to say things like:

    try (BufferedReader br = new BufferedReader(new FileReader(path)) {
    return br.readLine();
    }
    instead of:

    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
    return br.readLine();
    } finally {
    br.close();
    }
    based on having BufferedReader implement a Disposable interface.

  • Block expressions, a proposal from Neal Gafter to be allow things like:
    double pi2 = (double pi = Math.PI ; pi*pi)**; // pi squared*

    Basically, the principle here is that the (parenthesis-delimited) block would return a value.

  • Exception handling improvements, another proposal from Neal Gafter to allow things like:
    try {
    doWork(file);
    } catch (final IOException | SQLException ex) {
    logger.log(ex);
    throw ex;
    }

  • Improved Type Inference, a proposal from me (although I can't claim credit for the idea) to be able to replace things like this:
    Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
    with things like this:
    Map<String, List<String>> anagrams = new HashMap<>();

  • A new syntax for wildcard variance, again from the prolific Neal Gafter, allowing the user to replace "? extends" with "out" and "? super" with "in". (Can you tell that Neal's been working on C#?)

I don't love all of these proposals, but I do love some of them, and I think it is great to see that the pent-up demand for work on the Java language finally has an outlet.

(For those of you following the various Closures proposals: Closures don't count as a small change, and are therefore not in scope for this JSR.)

ETA: The "use Scala instead" and "where is BGGA?" comments have been made, so please read the comments and feedback before reiterating them.

34 comments:

Anonymous said...

WBJUS - http://cluonflux.com/article/34/why-bother-just-use-scala-continued

Yardena said...

Hi Jeremy,

Do you have any details/links for the declaration site variance proposal? It's not talked about much (the only reference I found was from last year QCon presentation), yet it would be a "big deal" feature.

Yardena.

Yardena said...

Nevermind, just found it.

Jeremy Manson said...

@anonymous - I'm pretty sure that even Martin Odersky wouldn't suggest that we all just abandon Java en masse and start using Scala. The languages are two different design points and, if nothing else, there is a rather large existing codebase and ecosystem of tools.

@yardea - I don't have information on it, but I suspect that would fall under the heading of "large language changes".

Jeremy Manson said...

@yardena - Sorry, I actually misinterpreted what you meant by declaration site variance. I thought you meant something more pervasive. Neal's proposal is very definitely small.

gruenewa said...

Please stop the "Small Language Changes for Java7"-Stupidity!

Instead of adding Automated Resource Blocks and new Foreach statements for Maps and things like this, they should simply add BGGA closures! With BGGA you get all this stuff for free!

Jeremy Manson said...

@gruenewa -- I'm not sure what part of BGGA would allow additional type inference or multiple exception catch. I'm pretty sure that Neal Gafter doesn't know what parts of BGGA would allow that, either, since he is an active participant in this process.

Martin Dobmeier said...

Yardena,

as far as I understand Neal's proposal is "just" about introducing an improved syntax for wildcards, but it's still all use-site variance. I don't think introducing declaration-site variance as in Scala or C# 4.0 (if I'm not mistaken) is going to happen. I like Scala's approach better, but it sounds like a major change if applied to Java ...

Cheers, Martin

Anonymous said...

i cant wait to use Java7. LOL!

Yardena said...

Jeremy and Martin - thanks a lot for responses. I wasn't sure what it was about before I looked at the google-doc. I see now it's just syntactic sugar over wildcards.

franci said...

Hi Jeremy,

this is what I think about these things:

Exception handling improvements would be great and very helpful for some algorithms, no doubts about this, I love it.

Improved Type Inference would be helpful for reading code, no doubts about this, I love it too.

Strings in Switch, maybe useful in some cases but not much and newbies are in risk of misusing it.

Automated Resource Blocks, it's very useful in order to reduce boilerplate, but again newbies are in risk of forgetting to free resources.

Block expressions, at this moment I don't like it, please not in java7.

A new syntax for wildcard variance, at this moment I prefer the current sintaxis, I can wait until java9 or even more :-)

I hope java will change slow and safe.

Anonymous said...

@franci:
>Automated Resource Blocks, it's very useful in order to reduce boilerplate, but again newbies are in risk of forgetting to free resources.

the whole point of the ARM lang. change is to eliminate the "risk of forgetting to free resources". when using the new syntax you won't need to close the resource - that will be done for you automatically (hence the name).

sboulay said...

I like the following changes
1.) the resource block
2.) multi catch
3.) new syntax for wildcards

My only concern with the resource block is that it could be implemented with closures - if we get them in java 8 that is. Other languages such as C# provide a "using" block and closures. I am not sure if they had their time they would only go with one approach and not both.

orip said...

I'd prefer "type inference" similar to C#'s:

var anagrams = new HashMap<String, List<String>>();

Alex Cruise said...

FWIW I'm the guy who started WBJUS and it wasn't me who posted the first comment. :)

Whether Martin wants people to switch to Scala in droves is immaterial--people are switching from Java and Sun appears to have no credible vision for how to keep us around.

JavaFX and Fortress are both pretty nice languages, but neither of them is making any attempt at the general-purpose programming language market.

I realize Sun is in dire straits and can't afford to spread themselves too thin, but their current underinvestment in programming language innovation is not going to help the situation.

Anonymous said...

Neal's IN and OUT enhancement should be definitely be forgotten. Those in/out parameters mean nothing in Java. C# has a reference vs. value notation. Who says an "in" parameter can't be written to? It's pure crap.

Robert Konigsberg said...

Two language enhancements I would really like to see are 1: multi-line strings and 2: easy-to-create exception classes. They're not popular, they're just my peeves.

James Iry said...

@Anonymous - it's not pure crap. In C# 4, the usages of "in" and "out" referenced are related to variance not pass-by-value vs pass-by-reference. Gafter's proposal is to use the same notation, albeit at each usage site instead of at the definition site, as a convenient mnemonic to understand and remember when it's useful to use ? extends Foo vs ? super Foo. For a better explanation of variance and how it relates to input/output than can be put in a little comment box see Wadler's book "Java Generics and Collections"

http://oreilly.com/catalog/9780596527754/

I'm with others that Scala/C# 4 style definition site variance would be even nicer, but it's a much larger language change than would be in scope for this project. Note, for the record, Scala can also do usage site variance. Scalars just do it a lot less.

I'm pretty sympathetic with the WBJUS crowd. Scala's approach is to unify and generalize things rather than have special cases. For instance, two proposals (strings in switch statements and multiple exception type matching) are unified in the single concept of pattern matching in Scala. And a third thing that is often suggested for Java, multiple value return, is also related to pattern matching in Scala. So one rich concept neatly covers what seems to be 3 very different things, plus a bunch more.

Similarly ARM, as @gruenewa and @sboulay mentioned, doesn't need language syntax if you have lamdbas - which in fact neatly cover things like what Java calls "enhanced for-loop". So again, many special language features can be covered by one general feature.

Finally, Scala is a very expression oriented language. So expressions in blocks aren't a special thing like @franci sees and fears. They're common and ordinary across most of the language.

One quibble with Jeremy's response to the WBJUS comment. Yes, there is a large existing codebase and ecosystem of tools for Java. But the codebase issue is covered just fine with Scala - mixed Scala/Java pretty much Just Works whether it's Java libraries or Java source. The tools side of the equation is more of an issue, true. Still, a great many of the tools work with byte code and so work with Scala. That said, of course there are plenty of tools (e.g. IDEs) that depend on Java syntax that Scala really can't take advantage of. The situation there is improving rapidly but Java is still far in the lead on that front. That and "developer base" are, IMHO, the only two real responses to @Alex's WBJUS. And developer base is surprisingly easy to fix - it's pretty trivial easy to teach Java devs how to "write Java in Scala" and then gradually teach them how to really use Scala.

pitpat said...

String in switch statements: Why not? In fact, why not objects of any arbitrary type? Even if it doesn't offer any performance improvements, a simple desugaring to if-then-else would be useful.

ARM block: Yes! The example of what we have to write today doesn't even tell the whole story. The fully proper code to write is

BufferedReader = null;
try {
br = new BufferedReader(new FileReader(path));
return br.readLine();
} finally {
if (br != null) {
try { br.close(); }
catch(IOException ignore) {}
}
}

ARMs would hide this mess. The full BGGA approach is too complicated.

Block expressions: Does not meet the power/weight threshold for new features.

Exception handling improvement: Sure, but I'm not crazy about the pipe syntax.

Improved type inference: yes!

New syntax for wildcard variance: does not meet power/weight threshold.

sicklittlemonkey said...

For automated resource blocks the try {} notation still a bit verbose for common cases. It only allows one resource (like C#'s syntax).

A keyword would be more concise:
transient BufferedReader = null;

Cheers,
Nick.

Jeremy Manson said...

@sicklittlemonkey -- Actually, the syntax in the proposal allows for multiple resources. I just didn't want to dump the entire proposal into the blog entry. It looks like this:

try (ResourceClass r1 = new ResourceClass();
    ResourceClass2 r2 = new ResourceClass2()
    // and so on...
  ) {
  // do stuff with r1 and r2...
}

sicklittlemonkey said...

Thanks for the reminder Jeremy. I last looked at this a year ago. But each resource has to be the same type, right?

Basically, what I want for xmas is to be able to pretend that I have locals with destructors. I'm not ashamed to admit that. ;-)

There is too much boilerplate try/catching in Java code. Adding a keyword would really collapse things down.

Scoping could be done manually if needed.

Cheers,
Nick.

Jeremy Manson said...

@nick - nope. This is a whole new proposal from Josh. The whole thing can be found here.

Jeremy Manson said...

@nick -- Oh, and at the risk of revealing too much about what I think, I agree with you about wanting locals with destructors. That's why I think that this shouldn't really have anything to do with closures -- it really has more to do with a given variable and its scope than it has to do with a block of code. In fact, my counterproposal to Josh was to introduce a new keyword at variable declaration time:

auto Resource r = new Resource();

The r.dispose() method would get reclaimed at the end of the scope. But he didn't like it very much, and I understand his reasons.

sicklittlemonkey said...

We are on the same page. Your "auto" is my "transient". (Chosen because it's already a keyword and backwards compatible for this use.)

And thanks for the link - an interesting read. Professional as always, Josh was nice enough to mention this alternative in his proposal:

"*Modifier in place of block* - An alterative to a block construct is a new modifier that could be added to any local variable declaration for a variable that extends Disposable. This is more flexible and less verbose, but more dissimilar to existing Java language constructs."

I understand his concern, but don't agree.

Cheers,
Nick.

Anonymous said...

How about this :

Function SomeFunName (BufferedReader br) {

return br.readLine();

[ try :

//Error handling code

]
}





- Logically Genius

franci said...

@Anonymous about "Automated Resource Blocks" what I tried to explain (and I haven't reached) is that newbies learning to program would not acquire (and neglected programmers will forget) are skills about free those disposable resources.

I see it every day, some neglected programmers do not free resources (and don't care about it) in languages that need it (like delphi).

That's not my case, I'm a pedantic programmer :-)

Kartik said...
This comment has been removed by the author.
Kartik said...

Hi Jeremy,

Do you think Nullable annotations is a enhancement small enough to make i into JDK7?

Sample example could be

public void doFoo(@Nullable Bar bar) {
.....
}

This would mean that bar instance can potentially be null.

Similarly you could configure a method to return non null values by using @NotNull annotations or something like that.

If IntelliJ idea has it, why can't JDK 7? It will reduce repititive code such as

str = str != null && str.length() > 0 : str : "";

Jeremy Manson said...

@Kartik -- This is in scope for JSR-305. Whether it actually gets done by JDK7 is not something I can predict.

Brenden said...

Oh yes, my favorite language change:

Please nuke #$@! \u escape sequences, at least in comments. Comments? Really? Jeebus I hate the fact that comments can be interpreted as anything other than straight up literal characters.

\u is OK in String literals. Anywhere else, it's just a bad idea waiting to trip up the unwary.

mutleythedog said...

31 comments??? Wow! Not bad for a complete boff like you..

Jeremy Manson said...

33! But it really isn't all that unusual.

Casper Bang said...

It's a long time ago I have been this little interested in a major version bump of Java. This is not innovation, it's inertia patching.
I'm seriously doubting whether we'll see a JDK8 with closures, and even if we will in 2012 or so, by then other languages will have moved even further ahead. No wonder Neal Gafter moved on.