New JEP: Concise Method Bodies
Remi Forax
forax at univ-mlv.fr
Fri Oct 5 23:06:02 UTC 2018
> De: "Brian Goetz" <brian.goetz at oracle.com>
> À: "Kevin Bourrillion" <kevinb at google.com>, "Alex Buckley"
> <alex.buckley at oracle.com>
> Cc: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Envoyé: Samedi 6 Octobre 2018 00:18:54
> Objet: Re: New JEP: Concise Method Bodies
>> Can the expression before the :: refer to any method parameters? Of course, it
>> would still expect to pass those parameters into the method, so it's weird to
>> have the same parameter used in both ways, but does it make sense to forbid it?
> Yes, it makes sense to forbid. Here's why.
> The framing of
> method declaration = behavior literal
> is meant to suggest that the thing on the RHS can be computed ONCE, and that's
> the "body" of the method. Therefore, it should only be computable based on what
> is known in the context of the method (static state for static methods,
> instance state for instance method.) It is not merely a shorthand for "take the
> method ref, turn it into a lambda, and then turn the body of that lambda into a
> method body."
> So the thing on the left of the :: must be something that could be, say, the RHS
> of a field initializer of the appropriate static-ness.
It makes little sense to me, because there is no assignment at runtime (it's not a field assignment), you are providing a rational for the semantics based on the syntax, it's the tail waging the dog.
To answer to Kevin,
begin able to decide a strategy with the parameter before delegating is not that uncommon, and the way to write it is
void fun(T1 arg1, T2 arg2) = getAStrategyAsAFunction(arg1, arg2)::apply
By example, if you want to write a Visitor that does the dispatch at runtime (a poor's man pattern matching), you need to first find the function to call given the class of the parameter and then delegate the call to that function.
public class Visitor {
private final HashMap<Class<?>, Consumer<Object>> map = new HashMap<>();
public <T> void register(Class<T> type, Consumer<? super T> consumer) -> map.put(type, o -> consumer.accept(type.cast(o)));
public void call(Object o) = map.get(o.getClass())::accept;
}
>> Now we want to introduce a second way to use method references, where that
>> creation/evaluation distinction doesn't exist.
> Same distinction. You can think of the creation as happening in <init> /
> <clinit>.
Methods are not assigned during <init> / <clinit>. Java is neither Ruby nor JavaScript. Otherwise, why do we need a conversion of a method to a functional interface (the :: operator), we should be able to use the method value directly, the one assigned, right ?
[...]
The only conclusion of this discussion is that supporting method reference for concise method body seems a very bad idea, because it will make people thinking that methods can be assigned like fields.
Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20181006/dfdf28ae/attachment-0001.html>
More information about the amber-spec-experts
mailing list