Yes, this type of thing is possible.  I think it would be limited to STC or SC 
since you would need to know the type of the receiver.  
org.codehaus.groovy.classgen.VariableScopeVisitor#visitMethodCallExpression is 
the bit of code that sees "var(...)" and replaces it with "var.call(...)".  
Maybe you could add a call method to the metaclass of the functional type that 
delegates to the SAM as an experiment.

You should be able to create an AST transformation that does this by looking 
for the INFERRED_TYPE node metadata of a MethodCallExpression's 
objectExpression.

https://issues.apache.org/jira/browse/GROOVY-5881 is a good ticket to look at 
and see how even the "call" substitution is limited in reality.


From: Christopher Smith <chry...@gmail.com>
Sent: Thursday, April 29, 2021 8:33 AM
To: dev@groovy.apache.org
Subject: Re: () call-type syntax for functional interfaces?

Sure, this is theoretically possible (though many functional interfaces aren't 
annotated), but the convenience I'm asking about would have to be compile-time, 
because it would depend on the declared type (which is part of why I suspect it 
might not even make semantic sense in the underlying dynamic model).

On Thu, Apr 29, 2021, 08:24 Rachel Greenham 
<rac...@merus.eu<mailto:rac...@merus.eu>> wrote:
Sorry if I might be teaching people to suck eggs, but you can discover the 
functional method of a functional interface through reflection. It’s a bit of a 
lookup but presumably in groovy the results of such lookups do get cached...

I use (reassembled from something that’s a bit more broken up than this):

Optional.of(Function.class)
    .filter(Class::isInterface)
    .filter(c -> c.isAnnotationPresent(FunctionalInterface.class))
    .stream()
    .flatMap(c -> Arrays.stream(c.getMethods()))
    .filter(Predicate.not(Method::isDefault)
        .and(m -> !Modifier.isStatic(m.getModifiers())))
    .findFirst()
    .map(Method::getName);

<< Optional[public abstract java.lang.Object 
java.util.function.Function.apply(java.lang.Object)]

Modify to allow any interface as long as it has only one abstract method by, 
instead of the .findFirst(), go to a list or array and only use it if it’s 
exactly one entry long.

--
Rachel Greenham
rac...@merus.eu<mailto:rac...@merus.eu>



> On 29 Apr 2021, at 12:46, Christopher Smith 
> <chry...@gmail.com<mailto:chry...@gmail.com>> wrote:
>
> That option is not available when using, for example, 
> java.util.function.Function.
>
> On Thu, Apr 29, 2021, 03:34 Angelo Schneider 
> <angelo.schnei...@oomentor.de<mailto:angelo.schnei...@oomentor.de>> wrote:
> Is that not already covered by the call() - method?
> I mean the option to declare a method called `Object call(args)´
> Best Regards
> Angelo
>
> ---
> Angelo Schneider
> angelo.schnei...@oomentor.de<mailto:angelo.schnei...@oomentor.de>
> +49 172 9873893
>
> > Am 29.04.2021 um 02:47 schrieb Christopher Smith 
> > <chrylis+gro...@gmail.com<mailto:chrylis%2bgro...@gmail.com>>:
> >
> > It would be convenient to be able to use the convention of "use
> > parentheses on a function-like object" with functional interfaces; for
> > example, if a variable is declared as type Function, to have
> > `myVar(3)` run `myVar.apply(3)`. Is there any chance this would be
> > practical, or would its semantics be limited sufficiently by the
> > default-dynamic nature of Groovy to not add value?
> >
> > (I have in mind Groovy's tendency to do runtime switcheroos with
> > anything that implements Map as a counterexample, but that may be
> > beside the point.)
>

Reply via email to