The explicit cast was needed before 2.2 only when you were trying to cast a 
Closure to an instance of an interface (or other SAM type). In my example, the 
closure implicitly can be casted to type X after 2.2. Before 2.2, you had to 
explicitly cast the closure to X.

Jochen's example worked because he didn't declare the type of his parameter. 
When no type is declared, "Object" is used, which will take the Closure 
directly.

I started out understanding Groovy by understanding how Groovy maps to Java 
code. The closure block is like an anonymous class block from Java, where you 
create a new instance extending Closure. That's why you can pass it where 
Object is needed but not where explicit type X is needed. Groovy allows ways to 
cast things more than Java does, for example in Groovy you can say "1 as 
String" to "cast" (convert) to a String -- in Java: 
"Integer.valueOf(1).toString()". For closures Groovy allows you to "cast" them 
to a proxy object implementing the target type, if that interface or abstract 
class has only one abstract method.

Jason

-----Original Message-----
From: alessio [mailto:aless...@gmail.com] 
Sent: Tuesday, December 01, 2015 3:39 PM
To: users@groovy.apache.org
Subject: Re: "External" closures, why?

On Tue, Dec 1, 2015 at 9:24 PM, Winnebeck, Jason 
<jason.winneb...@windstream.com> wrote:
> What was recently added is that you don't need to explicitly cast a closure 
> to a SAM (single abstract method), which was adding a feature to match Java 8 
> lambdas (that also don't need a cast). So if you have a method taking an SAM, 
> you no longer need to explicitly cast:
>
> interface X { void xf() }
> void func(X x) { x.xf() }
>
> func { println "Hello, World!" }
>
> It used to be before Groovy 2.2 that you had to call func this way:
>
> func({ println "Hello, World!" } as X)

Thanks, I am afraid I am getting lost though. Jochen's code from before (which 
ran just fine on 2.0) didnt have an explicit cast either. So why would I need 
one here, but not in his example

  def bar(shouldCall, toBeCalled) {
    if (shouldCall) return toBeCalled() else return null
  } // the returns are actually optional

  assert bar(true) {1} == 1
  assert bar(true, {1}) == 1 //alternative syntax

The only difference I can spot is that he did not specify an explicit type in 
his declaration. Is that the reason for the explicit cast pre-2.2?

>
> Closures are the closest equivalent to Java lambdas, but they do more than 
> lambdas because they support delegation (this is similar to setting "this" in 
> JavaScript closures, except in Groovy you detain both the delegate and the 
> original "this" -- as the "owner" field). Closures can also be queried for 
> the number of arguments they take, allowing overloading of closures that I 
> don't believe is possible with Java 8 lambdas. And of course with Groovy 
> closures work back to Java 5, so if you can't use Java 8 yet, you can use 
> Groovy.

I have already read about the owner and the delegate, have to admit though that 
it is not yet fully clear (but then I just started reading today :) ).

My main question is admittedly though less about the overall concept but the 
fact that you can pass a function outside of the method call.

My apologies for dwelling on this subject, but I am still baffled by this and 
find it quite confusing in terms of readability (maybe just my personal view :) 
). Why would the syntax allow for an argument to be outside of the call? Maybe 
somebody could explain the "historical"
reason or an actual case where that made sense.

Thanks

----------------------------------------------------------------------
This email message and any attachments are for the sole use of the intended 
recipient(s). Any unauthorized review, use, disclosure or distribution is 
prohibited. If you are not the intended recipient, please contact the sender by 
reply email and destroy all copies of the original message and any attachments.

Reply via email to