methods-in-methods, can they be static? Should they be externally accessible?

Remi Forax forax at univ-mlv.fr
Wed Jan 8 15:41:37 UTC 2020


----- Mail original -----
> De: "Reinier Zwitserloot" <reinier at zwitserloot.com>
> À: "amber-dev" <amber-dev at openjdk.java.net>
> Envoyé: Mercredi 8 Janvier 2020 15:41:38
> Objet: methods-in-methods, can they be static? Should they be externally accessible?

> In regards to:
> https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001904.html
> ('Towards Cleaner Nesting' - Brian Goetz)
> 
> My only comment to the majority of that post is to applaud it. From the
> text I gather that the most (to me, anyway) exotic aspect of the plan:
> methods in methods – are not really part of milestone 1.
> 
> 1.The 'local method branch' that Jesper and Maurizio were talking about
> last Saturday – is that about methods in methods? Is 'local method' the
> terminology for the concept of a method whose immediate enclosing lexical
> context is a method?

yes,
the JLS uses local class for a class inside a method, so a method inside a method is a local method.

> 
> 2. Is it too early to talk about the semantics of methods in methods? Just
> in case I misinterpreted the term 'local method' (see #1), I'm going to use
> the term 'inner method' for any method whose immediate enclosing instance
> is itself a method.
> 
> Syntactically, you can of course put the modifier 'static' on an inner
> method. But what does that mean? Clearly it means you cannot access the
> (non-static) fields of the instance that the enclosing method is in, even
> if your enclosing method is itself non-static. That is obvious. However, if
> I apply Brian's sense of what static means (namely: The lexical context of
> a static anything is solely for namespacing purposes, not for access), it
> would also mean I have no access to any (effectively) final local variables
> declared 'above' me in the enclosing method – something method local
> classes (and, presumably, non-static inner methods) DO get. This also
> conveniently means the inner method can actually be hoisted up to the class
> level by the compiler verbatim; nothing the method could possibly access
> requires synthetic bridgers, the way captured local vars are currently
> transmitted to method local classes via synthetic constructors.
> 
> Do I follow Brian's thought process on what 'static' means correctly and,
> thus, will static inner methods be allowed?

a local method is like a named lambda, the best should be that everything you can do with a lambda, you can do it with a local class, retrofittingly seing a lambda has a nameless local method.

a static local method means you are independent of any implicit instances, local variables and type parameters, you can see it as a way to clean the scope (it's not fully true because you can still access to all static thingy in the scope).

> 
> 3. If static inner methods are indeed allowed, any thoughts on allowing
> code that isn't in the outer method to invoke the inner method? The point
> of 'inner methods' is presumably that they are relevant only to the outer
> method and thus this seems to go against the idea, but, for unit tests I
> can foresee some utility in being able to do this. However, because of the
> separated namespace rules (fields and methods each are their own
> namespace), what would the syntax look like? Given:
> 
>    class Example {
>        int instanceOuter = 10;
>        void instanceOuter() {
>            static boolean inner() { return true; }
>        }
>    }
> 
> How would one invoke the inner method from, say, a unit test class in the
> same package for the Example class? Example.instanceOuter.inner() is
> tricky. Example::instanceOuter.inner() doesn't really feel right, though I
> believe syntactically that can be made to work.
> 
> Before we get bogged down in syntax debates, is this use case (unit tests)
> worthwhile enough to try to find a way?

You can not write a unit tests for a lambda.
So you can not write a unit test for a local method.

That said, i think we will have to revisit the operator :: and give a meaning to ::foo, something we have chosen not to do when designing lambdas.
The other solution is to have a way to talk about the context of a method but it seems a weird concept.

There are other things to discuss
- the fact that you may be able to omit the return type the same way a lambda omit the return type
  (with the problem of recursive local methods)
- the arrow syntax, should the arrow syntax only available to lambdas or available to any methods.

> 
>  --Reinier Zwitserloot

Rémi


More information about the amber-dev mailing list