Loosening requirements for super() invocation

Brian Goetz brian.goetz at oracle.com
Wed Jan 25 21:56:59 UTC 2023


>     So, let's look at the grammar.  Where does the production that
>     matches `super(e)` come from?  Its from ConstructorBody:
>
>         ConstructorBody:
>         { [ExplicitConstructorInvocation] [BlockStatements] }
>
>     If you pull on the string for BlockStatements, you'll see a whole
>     nest of statement forms, *none of which match this(e) or
>     super(e)*.  So to allow one of these statements inside a block,
>     you have to refactor all the statement productions in the
>     language.  Then you have to go through the entire spec and
>     prohibit these in the places where they can't be used (such as
>     lambdas.)
>
>
> OK now I understand - thanks for being patient :)
>
> I didn't realize that the restriction that super()/this() must be 
> first in a constructor was actually implemented using the language 
> grammar.
>
> But it doesn't have to be that way, does it? I mean, the grammar 
> allows "foobar()" to appear in any method, even when "foobar()" cannot 
> be resolved. The requirement for "foobar()" to be resolvable is stated 
> elsewhere, outside of the grammar.

Specification is like programming in some ways.  There are many ways we 
could implement something.  Sometimes we prefer some ways because they 
are better than others; other times we prefer some ways because that's 
how we've been doing it for a long time and we've built up a large set 
of dependencies (some implicit) on that way of doing it. If you want to 
change a base assumption in a mature codebase, you should expect a 
higher effort, greater disruption, and more risk. It's the same way with 
spec, but probably more so.

Justifying a feature like this is based on costs, risks, benefits, and 
priorities.  A feature with lower cost or risk is easier to justify.  
Doing a 40% smaller feature (just going by your "3 out of 5" estimate) 
at 95% lower cost (making up a number here, but the difference appears 
significant) seems worth considering carefully.

> So why not, in the grammar, allow super()/this() to appear anywhere 
> that any other method call can appear, and then layer on the 
> restriction that they may only appear in constructors as a separate 
> (English) sentence?

That can be done, at a cost and at risk.  The cost is "how many places 
do you have to say this", and the risk is "what are the chances you've 
identified all of them."  If I can reduce this cost and risk to zero, 
that's attractive.

> It makes intuitive sense that we would need to do it this way because 
> (as the JEP describes) we're converting a syntactic requirement into a 
> semantic one.

But that's my point -- there's a simpler feature which feels like 90+% 
of the benefit that doesn't have this requirement.  The existing 
approach used here is quite clever -- and can be expanded a fair bit 
without having to make a wholesale change of direction.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20230125/111d049c/attachment.htm>


More information about the amber-dev mailing list