Concise Method Bodies feedback
brian.goetz at oracle.com
Wed Oct 10 13:05:21 UTC 2018
Thanks for taking the time to pen these thoughts (and for waiting a bit to give your initial subjective reaction a voice.) In many ways, these are the “obvious” reactions (in the sense that, I usually do a “what reactions might I expect” exercise before I send something out, and all of these were on the list, so that’s good), so let me share the “obvious” context and counter-arguments.
> My first reaction to concise method bodies was "yuck”.
I expected a lot of people to have this reaction. And also a lot would have the other reaction. So far, my expectations have been confirmed :) So, ++subjectiveYuck noted :)
The idea didn’t come from nowhere; C# added it a while back, and Scala and Kotlin have similar features. And over the years, a lot of programmers who like these languages have bent my ear about it. So while there are obvious counter-arguments, there is also a certain amount of pent-up desire for it.
At first, my reaction was the same as yours — “not worth it.” But, as I worked through the Amber programme, and the theme of “needless repetition is where bugs hide” came up over and over again, it started to grow on me, especially the “equals” form. I also found myself using it when writing code on whiteboards and such. So I felt it deserved a broader airing.
> That adding this to Java will be adding a lot of style discussions and
> mental overload for something that mostly seems pretty low value.
Yes, I discussed this exact concern with the C# stewards a while back, to see what the arc of reaction and adoption was in their community. They allowed as how there was an initial period of “style guide wars” as people grappled with the right way to use this feature (you listed a number of such issues), and that the initial round generated the expected share of noise and angst, but that eventually things equilibrated to a pretty reasonable balance, and that in the end, people are quite happy to have the feature, and would be sad to lose it.
> (and certainly making it harder to read)?
People have a tendency to level the “hard to read” accusation against any new feature they don’t love. But, the C# community took about 5 minutes to get over this; I have full confidence that the Java community would be the same.
> One of my first reactions was also the lack of consideration of
Oh, there was a lot of consideration for this. In APIs, where Javadoc often overwhelms code — and which describes most of the code I write — I agree this feature is mostly silly.
But, now let’s talk about the other 99% of Java code out there. The vast, vast majority of Java code has NO JAVADOC WHATSOEVER. It is implementation code for domain data and logic — and way too much of it. These people are in pain, and that’s who this feature is for. (I can understand how this would be confusing, because ordinarily we over-rotate towards the needs of library developers in selecting language features. This one is for everyone else. We’re allowed to do that once in a while.)
OK, so will this feature save those guys? Of course not. There are many other sources of needless boilerplate, and we’re thinking about all of them, and may be ready to propose features for some more of them soon. This one was simplest, so it escaped the lab first.
> I can't say I've ever felt that
> the braces on a method are holding me back and the discussion so far
> isn't selling it as a feature.
Fair. Just bear in mind that others feel differently. I hear a lot of opinions about the experience of coding in Java (and other languages). My job is to balance them.
> (Its not too early to talk syntax, when the feature is mostly syntactic)
OK, so just bear in mind that this exchange will probably have used up the entire quota for public syntax discussion until the feature is otherwise perfect.
> For the method ref form, I'm not sold on full expressions on the LHS
> of :: particularly wrt when the expression is evaluated.
That’s not syntax, so I won’t hold it against the quota. This is a fair concern, and you’ll see that such things are being discussed on a-s-e. I think it would be reasonable to restrict the LHS to final fields, which eliminates a number of timing questions, and likely preserves all the important use cases. But, I’d rather complete the exploration of possible use cases before clamping down. Prematurely narrowing the scope often results in missing an important use case or interaction.
> For the expression form, the semantics are obvious, but the need seems
> very low. A method can be written on one line today, so this saves
> very little, and at a high cost.
I don’t necessarily disagree with the conclusion, but the claim of “high cost” is … excessive. (I get it, you don’t think the benefits outweigh the costs. Totally fair. Say that instead.)
> I'm not a fan of either the = or arrow syntax here. The equals is
> understandable, but does make the code blend into instance variables
> when written without comments (I'm sure there is a puzzler there...).
> The arrow is being subverted again. It should be just for mobile code,
> whereas the code here runs in the context you see.
If anything, I’d put it the opposite way. There are valid objections (and probably valid alternatives) to using equals here, but to suggest anything but the arrow for the expression form seems ... silly.
> I really struggle with the expression form. It just seems to be adding
> complexity, making code harder to write and harder to read. Could the
> solution be to keep method ref form and dump the expression form?
I agree that most of the power is in the delegation form, because it is more than mere concision — it is a higher-level declaration of implementation by delegation, and capturing that is valuable. It also eliminates more repetition (the arguments) than the expression form. (Why do we have method refs, when lambdas will do the job? Because names matter, and saying “that method over there” is clearer than a bag of imperative code that calls it. Same story.)
But, I think the two features support each other, in that by having both, we arrive at a regular 3x2 grid of (statements, expression, delegate) x (method declaration, behavioral expression) scheme for describing invocable behavior. Dropping one creates an irregularity in this scheme, and such irregularities have a cost too — they make the language harder to learn, understand, and reason about. So I think they swim or sink together, because the regularity strengthens both of them. (I know you didn’t value this aspect for switch, so I don’t expect you will value it here either.)
More information about the amber-dev