Tobia
Tobia

Reputation: 18811

Is there a way to refer to an operator as a two-argument closure?

Sometimes I need to pass an operator as a closure, like this:

do.some.thing() { x,y -> x+y }

I'm wondering if there is any shorthand "operator pointer" syntax, analogous to the "method pointer" syntax, that would give me the operator already wrapped into a two-argument closure.

I see that most arithmetic operators are available as methods on Number and related classes:

public Number plus(Number right)

Add two numbers and return the result.

but they are instance methods and I can't figure out if I can use the method pointer operator .& to turn them into a two-argument closure.

Upvotes: 1

Views: 150

Answers (2)

tim_yates
tim_yates

Reputation: 171084

You can do this sort of thing as well...

Not sure uncurry is the right term, but it's almost right ;-)

import org.codehaus.groovy.runtime.MethodClosure

def uncurry(MethodClosure c) {
    {a, ...b -> a."$c.method"(*b) }
}

Then, to make a 2 arg closure from Number.plus, you can do:

def plus = uncurry(Number.&plus)

And then:

assert plus(1, 2) == 3

Which also works with other method handles as well:

def collate = uncurry(List.&collate)
assert collate([1, 2, 3, 4, 5], 2, true) == [[1, 2], [3, 4], [5]]

Upvotes: 5

Emmanuel Rosa
Emmanuel Rosa

Reputation: 9885

No, there's no such operator.

The method pointer operator won't work because the MethodClosure it creates basically has an object, in this case the Number class, and a method name. So if you do...

def c = Number.&plus

Then calling c will attempt to call plus() on the Number class, which of course won't work.

The only shortcut I can think of is to declare your operator closures once and simply reuse them as needed.

Upvotes: 3

Related Questions