Resolving Closures as functional interfaces

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Resolving Closures as functional interfaces

Nathan Harvey
Java 8 gave some good concrete types for functional programming, but Groovy does not interlope well with these new types. Consider the following methods:

public static void handle(Function function)
public static void handle(Runnable runnable)

And the following code:
handle({ arg -> return arg * 2 })

It would seem obvious that this should reference the handle(Function) method - it takes an argument and returns a value. However, it uses the handle(Runnable) method. More examples of a breakdown, in terms of the most logical resolution:

// Consumer, Function, Closure
{ arg -> println arg }
// Supplier or Callable, Closure
{ -> return 'Hello' } 
// Function, Closure
{ arg -> return arg * 2}

I have a sneaking suspicion that something on the parrot branch will have this fixed. If not, how would this be fixed? It's my understanding that methods are picked at runtime, so maybe a change to metaclass? I would love some direction on this.

Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Resolving Closures as functional interfaces

Jochen Theodorou

On 17.08.2017 08:39, Nathan Harvey wrote:
> Java 8 gave some good concrete types for functional programming, but Groovy does not interlope well with these new types. Consider the following methods:
>
> public static void handle(Function function)
> public static void handle(Runnable runnable)
>
> And the following code:
> handle({ arg -> return arg * 2 })
>
> It would seem obvious that this should reference the handle(Function) method - it takes an argument and returns a value. However, it uses the handle(Runnable) method.

That is because Closure implements Runnable and Callable.

> More examples of a breakdown, in terms of the most logical resolution:
>
> // Consumer, Function, Closure
> { arg -> println arg }
> // Supplier or Callable, Closure
> { -> return 'Hello' }
> // Function, Closure
> { arg -> return arg * 2}

without overloads you should have no problem, right?

> I have a sneaking suspicion that something on the parrot branch will have this fixed.

I don't think so, because this is groovy.lang.Closure, not the parser.
In static compilation this is a different matter of course

> If not, how would this be fixed? It's my understanding that methods are picked at runtime, so maybe a change to metaclass? I would love some direction on this.

well, can we really select Function over Runnable if the object we make
the call with, the Closure is a Runnable and no Function?

For me this means Closure should maybe not implement Runnable then... or
not in all cases. Same for Callable. Not a a difficult change... just
need move the implementation of the interfaces of these to where we do
the generated closure. But it is a breaking change for users of Closure
itself. That makes it no fast change

bye Jochen