You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@groovy.apache.org by alessio <al...@gmail.com> on 2015/12/01 17:18:59 UTC

"External" closures, why?

Hi,

I have just started to dig into Groovy and have been mostly impressed
by what it offers, however when I had a look at handling database
calls (http://docs.groovy-lang.org/latest/html/api/groovy/sql/Sql.html)
I stumbled upon a rather weird syntax

  sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle']) {
       // process row
   }

Usually I'd say this is a "regular" block scope but in this context it
was obviously a closure/function pointer/callback. It took me a while
to dig into this to find out that it can also be passed as second
argument to the method and was added in 2.2

  http://www.groovy-lang.org/semantics.html#_calling_a_method_accepting_a_sam_type_with_a_closure
  https://issues.apache.org/jira/browse/GROOVY-6188 (the JSR link does
not work anymore)

My question now is, why? Apparently pre-2.2 one had to cast the
closure to the appropriate type. But why making it possible to
actually define the closure outside of the respective call?

At least for me this is HIGHLY confusing.

Thanks

Re: "External" closures, why?

Posted by Owen Rubel <or...@gmail.com>.
He's not saying it's new.... only new to him. He is new to Groovy so alot
of principles we take for granted and that we forget ARE new for people in
the Java community can sometimes be confusing as well as exciting.

Hopefully we can keep people focused on the exciting :)

Owen Rubel
415-971-0976
orubel@gmail.com

On Tue, Dec 1, 2015 at 8:44 AM, Jochen Theodorou <bl...@gmx.org> wrote:

> The syntax is not new, Groovy had this kind of "attached block" since pre
> Groovy 1.0 times.
>
> Example:
>
> def foo(c) {c()}
> assert foo {1} == 1
>
> 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
> assert bar(false) {1} == nulll
> assert bar(false, {1}) == nulll //alternative syntax
>
> This kind of block usage w
> As for the semantics... The type conversion was done to align Groovy with
> JDK8 lambda expressions a bit. Lambda expressions in Java are a bit what
> groovy.lang.Closure is used for in Groovy, of course with more limitations
> for Java.... but while we depend on a single type and use meta information
> to know how many parameters this has and what types they declare for their
> usage, the Java solution was to not have a base class for lambdas. Instead
> the lambda is converted at runtime (it is a method in the declaring class
> plus a dynamic proxy to call that method using invokedynamic) to a SAM
> type. SAM means "single abstract method" and in Java specifically an
> interface with a single abstract method (static and default methods are not
> counted in here of course).
>
> bye Jcohen
>
> > Gesendet: Dienstag, 01. Dezember 2015 um 17:18 Uhr
> > Von: alessio <al...@gmail.com>
> > An: users@groovy.incubator.apache.org
> > Betreff: "External" closures, why?
> >
> > Hi,
> >
> > I have just started to dig into Groovy and have been mostly impressed
> > by what it offers, however when I had a look at handling database
> > calls (http://docs.groovy-lang.org/latest/html/api/groovy/sql/Sql.html)
> > I stumbled upon a rather weird syntax
> >
> >   sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle']) {
> >        // process row
> >    }
> >
> > Usually I'd say this is a "regular" block scope but in this context it
> > was obviously a closure/function pointer/callback. It took me a while
> > to dig into this to find out that it can also be passed as second
> > argument to the method and was added in 2.2
> >
> >
> http://www.groovy-lang.org/semantics.html#_calling_a_method_accepting_a_sam_type_with_a_closure
> >   https://issues.apache.org/jira/browse/GROOVY-6188 (the JSR link does
> > not work anymore)
> >
> > My question now is, why? Apparently pre-2.2 one had to cast the
> > closure to the appropriate type. But why making it possible to
> > actually define the closure outside of the respective call?
> >
> > At least for me this is HIGHLY confusing.
> >
> > Thanks
> >
>

Aw: "External" closures, why?

Posted by Jochen Theodorou <bl...@gmx.org>.
The syntax is not new, Groovy had this kind of "attached block" since pre Groovy 1.0 times. 

Example:

def foo(c) {c()}
assert foo {1} == 1

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
assert bar(false) {1} == nulll
assert bar(false, {1}) == nulll //alternative syntax

This kind of block usage w
As for the semantics... The type conversion was done to align Groovy with JDK8 lambda expressions a bit. Lambda expressions in Java are a bit what groovy.lang.Closure is used for in Groovy, of course with more limitations for Java.... but while we depend on a single type and use meta information to know how many parameters this has and what types they declare for their usage, the Java solution was to not have a base class for lambdas. Instead the lambda is converted at runtime (it is a method in the declaring class plus a dynamic proxy to call that method using invokedynamic) to a SAM type. SAM means "single abstract method" and in Java specifically an interface with a single abstract method (static and default methods are not counted in here of course). 

bye Jcohen

> Gesendet: Dienstag, 01. Dezember 2015 um 17:18 Uhr
> Von: alessio <al...@gmail.com>
> An: users@groovy.incubator.apache.org
> Betreff: "External" closures, why?
>
> Hi,
> 
> I have just started to dig into Groovy and have been mostly impressed
> by what it offers, however when I had a look at handling database
> calls (http://docs.groovy-lang.org/latest/html/api/groovy/sql/Sql.html)
> I stumbled upon a rather weird syntax
> 
>   sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle']) {
>        // process row
>    }
> 
> Usually I'd say this is a "regular" block scope but in this context it
> was obviously a closure/function pointer/callback. It took me a while
> to dig into this to find out that it can also be passed as second
> argument to the method and was added in 2.2
> 
>   http://www.groovy-lang.org/semantics.html#_calling_a_method_accepting_a_sam_type_with_a_closure
>   https://issues.apache.org/jira/browse/GROOVY-6188 (the JSR link does
> not work anymore)
> 
> My question now is, why? Apparently pre-2.2 one had to cast the
> closure to the appropriate type. But why making it possible to
> actually define the closure outside of the respective call?
> 
> At least for me this is HIGHLY confusing.
> 
> Thanks
> 

Re: "External" closures, why?

Posted by Guillaume Laforge <gl...@gmail.com>.
Also it gives more flexibility in terms of DSLs people can write.

You can create your own control structures that look like built-in ones.

For instance imagine you want to have an "unless" pseudo-statement, you
could write it like that:

void unless(boolean b, Closure body) { if (!b) body() }

and be able to call it like an "if" statement:

unless(condition) {
    // do something
}

which is indeed equivalent to:

unless(condition, { /* do something */ })

Guillaume

On Tue, Dec 1, 2015 at 5:23 PM, Søren Berg Glasius <so...@glasius.dk>
wrote:

> Hi Alessio,
>
> It's not a problem to use the closure like this:
>
> sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle'], {
>   // process row
> })
>
> it is simply a matter of how you place your parentesees
>
> When you use closures with collections you would offen omit the
> parentheses all together:
>
> collection.each {
>    // do something with it
> }
>
> but writing
>
> collection.each ({
>    // do something with it
> })
>
> yields the same result, but is a tiny bit more verbose
>
> Best regards / Med venlig hilsen,
> Søren Berg Glasius
>
> Hedevej 1, Gl. Rye, 8680 Ry, Denmark
> Mobile: +45 40 44 91 88, Skype: sbglasius
> --- Press ESC once to quit - twice to save the changes.
>
> On December 1, 2015 at 17:19:07, alessio (alessino@gmail.com ) wrote:
>
> Hi,
>
> I have just started to dig into Groovy and have been mostly impressed
> by what it offers, however when I had a look at handling database
> calls (http://docs.groovy-lang.org/latest/html/api/groovy/sql/Sql.html)
> I stumbled upon a rather weird syntax
>
> sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle']) {
> // process row
> }
>
> Usually I'd say this is a "regular" block scope but in this context it
> was obviously a closure/function pointer/callback. It took me a while
> to dig into this to find out that it can also be passed as second
> argument to the method and was added in 2.2
>
>
> http://www.groovy-lang.org/semantics.html#_calling_a_method_accepting_a_sam_type_with_a_closure
> https://issues.apache.org/jira/browse/GROOVY-6188 (the JSR link does
> not work anymore)
>
> My question now is, why? Apparently pre-2.2 one had to cast the
> closure to the appropriate type. But why making it possible to
> actually define the closure outside of the respective call?
>
> At least for me this is HIGHLY confusing.
>
> Thanks
>
>


-- 
Guillaume Laforge
Apache Groovy committer & PMC member
Product Ninja & Advocate at Restlet <http://restlet.com>

Blog: http://glaforge.appspot.com/
Social: @glaforge <http://twitter.com/glaforge> / Google+
<https://plus.google.com/u/0/114130972232398734985/posts>

Re: Re: "External" closures, why?

Posted by alessio <al...@gmail.com>.
On Wed, Dec 2, 2015 at 9:57 AM, Jochen Theodorou <bl...@gmx.org> wrote:
>
> yes, unless you include expressions with "new" in the term function call. Because in that case we do anonymous inner classes like in Java. I am mentioning this explicitly, because this is something we had to change (well, quite long ago already) after 1.0 I think.. maybe in 1.8... I don't remember clearly.

Thanks a lot for the clarification.

Aw: Re: "External" closures, why?

Posted by Jochen Theodorou <bl...@gmx.org>.
[...]
> So, just for yet another better understanding, whenever there is a
> code block (-> closure) after a function call, it automatically gets
> appended as additional argument?

yes, unless you include expressions with "new" in the term function call. Because in that case we do anonymous inner classes like in Java. I am mentioning this explicitly, because this is something we had to change (well, quite long ago already) after 1.0 I think.. maybe in 1.8... I don't remember clearly.

Re: "External" closures, why?

Posted by Schalk Cronjé <ys...@gmail.com>.
Exactly!

Good DSLs are charactetised by semantic expressiveness and readability. 
DSLs are either external (custom, dedicated parser) or internal (relying 
on the parse of the underlying programming language). Programming 
languages that enforces too much structure, lead to less readable DSLs. 
That is why languages such as Groovy and Ruby are excellent for DSLs, 
but C++, Java & C# are not.



On 02/12/2015 10:16, Cédric Champeau wrote:
> I don't think any discussion that is centered around this topic of 
> being possible to put the closure out of the parens will ever bring 
> anything. Groovy had it for a long time, and it's one of the main 
> things that make it suitable for human readable DSLs. Just compare the 
> readability of builders. If we had to write:
>
> html({
>    head({ title('Damn ugly' )})
>    body({
>       div([class:'main'], { p('foo') })
>    })
> })
>
> instead of what we can do today:
>
> html {
>     head { title 'Groovy' }
>     body {
>        div(class: 'main') { p 'foo' }
>     }
> }
>
> No doubt I would never have chosen Groovy to build DSLs.
>
> 2015-12-02 1:14 GMT+01:00 alessio <alessino@gmail.com 
> <ma...@gmail.com>>:
>
>     >
>     > yes
>
>     Thanks.
>
>     >
>     > the problem simply is that while(x, {doSomething()}) looks quite
>     ugly ;)
>
>     It absolutely does, agreed (but then all these inlined functions do in
>     most languages :) ).
>     Nonetheless, while visually maybe not appealing, I'd argue it makes
>     semantically more sense to have it in that place than "suddenly"
>     outside of the function call.
>
>     And yes, I understood that the regular way is still possible, my
>     "complaint" was rather about this additional alternative, which really
>     left me staring at the screen for a good while today (possibly
>     similarly as when I discovered Angular's insanity of using the
>     argument names for dependency injection - different subject though).
>
>     Anyhow, thanks for having taken the time to explain the details.
>
>     >
>     > if ultimate means last argument, then yes ;)
>
>     It does :)
>     Thanks for the clarification.
>
>     So, just for yet another better understanding, whenever there is a
>     code block (-> closure) after a function call, it automatically gets
>     appended as additional argument?
>
>


-- 
Schalk W. Cronjé
Twitter / Ello / Toeter : @ysb33r


Re: "External" closures, why?

Posted by Cédric Champeau <ce...@gmail.com>.
I don't think any discussion that is centered around this topic of being
possible to put the closure out of the parens will ever bring anything.
Groovy had it for a long time, and it's one of the main things that make it
suitable for human readable DSLs. Just compare the readability of builders.
If we had to write:

html({
   head({ title('Damn ugly' )})
   body({
      div([class:'main'], { p('foo') })
   })
})

instead of what we can do today:

html {
    head { title 'Groovy' }
    body {
       div(class: 'main') { p 'foo' }
    }
}

No doubt I would never have chosen Groovy to build DSLs.

2015-12-02 1:14 GMT+01:00 alessio <al...@gmail.com>:

> >
> > yes
>
> Thanks.
>
> >
> > the problem simply is that while(x, {doSomething()}) looks quite ugly ;)
>
> It absolutely does, agreed (but then all these inlined functions do in
> most languages :) ).
> Nonetheless, while visually maybe not appealing, I'd argue it makes
> semantically more sense to have it in that place than "suddenly"
> outside of the function call.
>
> And yes, I understood that the regular way is still possible, my
> "complaint" was rather about this additional alternative, which really
> left me staring at the screen for a good while today (possibly
> similarly as when I discovered Angular's insanity of using the
> argument names for dependency injection - different subject though).
>
> Anyhow, thanks for having taken the time to explain the details.
>
> >
> > if ultimate means last argument, then yes ;)
>
> It does :)
> Thanks for the clarification.
>
> So, just for yet another better understanding, whenever there is a
> code block (-> closure) after a function call, it automatically gets
> appended as additional argument?
>

Re: "External" closures, why?

Posted by alessio <al...@gmail.com>.
>
> yes

Thanks.

>
> the problem simply is that while(x, {doSomething()}) looks quite ugly ;)

It absolutely does, agreed (but then all these inlined functions do in
most languages :) ).
Nonetheless, while visually maybe not appealing, I'd argue it makes
semantically more sense to have it in that place than "suddenly"
outside of the function call.

And yes, I understood that the regular way is still possible, my
"complaint" was rather about this additional alternative, which really
left me staring at the screen for a good while today (possibly
similarly as when I discovered Angular's insanity of using the
argument names for dependency injection - different subject though).

Anyhow, thanks for having taken the time to explain the details.

>
> if ultimate means last argument, then yes ;)

It does :)
Thanks for the clarification.

So, just for yet another better understanding, whenever there is a
code block (-> closure) after a function call, it automatically gets
appended as additional argument?

Re: "External" closures, why?

Posted by Jochen Theodorou <bl...@gmx.org>.
Am 02.12.2015 um 00:17 schrieb alessio:
>>
>> should work in any Groovy version. The difference here is that for this to
>> work we can use any class being a parent to groovy.lang.Closure plus the
>> class itself of course. In the case here I did not give a type, which is
>> equal to using the base type of all types in Java and Groovy, which is
>> java.lang.Object
>
> Thanks for the clarification, this also seems to go along with what
> Jason wrote before.
>
> Could you just confirm if my previous summary below is correct then?
> If so I guess I understood what 2.2 introduced ...
>
>    "So before 2.2 the cast was necessary in order to satisfy the method
>    signature argument-wise, with a single Object argument being the
>    default (and hence not requiring a cast)?"

yes

[...]
> Purely from a personal point of view I'd probably stay away from sugar
> coating user-level functions to mimic native language elements as in
> the given example but then, I am not a language designer :)

the problem simply is that while(x, {doSomething()}) looks quite ugly ;)

On a side note: I actually strife to reduce native language elements 
where it makes sense. Of course I don't want another Lisp as well. Not 
that I finde Lisp bad, it is just nothing for the Java/Groovy world.

> Could you please just let me know if my previous assumption below is
> correct as well?
>
>    "it only works if the method expects the closure as ultimate argument.
>    In that case it can be appended outside, otherwise not."

if ultimate means last argument, then yes ;)

bye Jochen


Re: "External" closures, why?

Posted by alessio <al...@gmail.com>.
>
> should work in any Groovy version. The difference here is that for this to
> work we can use any class being a parent to groovy.lang.Closure plus the
> class itself of course. In the case here I did not give a type, which is
> equal to using the base type of all types in Java and Groovy, which is
> java.lang.Object

Thanks for the clarification, this also seems to go along with what
Jason wrote before.

Could you just confirm if my previous summary below is correct then?
If so I guess I understood what 2.2 introduced ...

  "So before 2.2 the cast was necessary in order to satisfy the method
  signature argument-wise, with a single Object argument being the
  default (and hence not requiring a cast)?"

>
> if you forget about lambdas and function pointers and such for a moment and
> simply think of a while loop:
>
> while (x) { doSomething() }
>
> then you will recognize this as perfectly in synch with the attached blocks
> I mentioned - of course only on the syntax level. On the semantic level
> there is a bit more than that.

Alright, fair enough. This example also reflects what Guillaume
mentioned in a previous reply with his unless() example.

Purely from a personal point of view I'd probably stay away from sugar
coating user-level functions to mimic native language elements as in
the given example but then, I am not a language designer :)

Could you please just let me know if my previous assumption below is
correct as well?

  "it only works if the method expects the closure as ultimate argument.
  In that case it can be appended outside, otherwise not."


Thanks again!

Re: "External" closures, why?

Posted by Jochen Theodorou <bl...@gmx.org>.
Am 01.12.2015 um 20:56 schrieb alessio:
> On Tue, Dec 1, 2015 at 5:44 PM, Jochen Theodorou <bl...@gmx.org> wrote:
>> The syntax is not new, Groovy had this kind of "attached block" since pre Groovy 1.0 times.
>
> Alright, I did just run the code with against 2.0 (which was supposed
> not to support it) and it ran just fine.
 >
> But then, what does the documentation refer to when it says one can
> omit an explicit coercion as of 2.2?

example:

interface SamType{ int foo()}

def callFoo(SamType t) {t.foo()}
assert callFoo {1} == 1

this example would throw a MissingMethodException before Groovy 2.2, 
while this one here:

def callClosure(t) {t.call()}
assert callFoo {1} == 1

should work in any Groovy version. The difference here is that for this 
to work we can use any class being a parent to groovy.lang.Closure plus 
the class itself of course. In the case here I did not give a type, 
which is equal to using the base type of all types in Java and Groovy, 
which is java.lang.Object

>
>>
>> This kind of block usage w
>
> Something is missing here.

yes, sorry... some sleep and a proper email client ;)

[..]
> So far so good, the concept itself is not that much of a problem, the
> thing that I was simply wondering (and which confused the heck out of
> me :) ) is the choice to support mentioned form of passing the
> closure, which IMVHO could be utterly confusing, as the passed
> function is VISUALLY not part of the function call but "dangling"
> somewhere near it.

if you forget about lambdas and function pointers and such for a moment 
and simply think of a while loop:

while (x) { doSomething() }

then you will recognize this as perfectly in synch with the attached 
blocks I mentioned - of course only on the syntax level. On the semantic 
level there is a bit more than that.

And it so happens, that the most common usage of this syntaxis to 
provide a custom looping method to execute an action for each iteration:

list.each { println it }

This will iterate over all elements in the list and print them out.

bye Jochen

RE: "External" closures, why?

Posted by "Winnebeck, Jason" <Ja...@windstream.com>.
Jochen's example never required a cast in any Groovy version because his method took Object (a super type of Closure).

Had Jochen defined an interface, and defined the method to take the interface instead of Object or Closure, then before 2.2 an explicit cast from Closure to the interface type would have been required. After 2.2, Groovy implicitly converts the Closure to the interface type without the cast.

Jason

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

On Tue, Dec 1, 2015 at 9:48 PM, Winnebeck, Jason <Ja...@windstream.com> wrote:
> 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.

So before 2.2 the cast was necessary in order to satisfy the method signature argument-wise, with a single Object argument being the default (and hence not requiring a cast)? Did I get that right?

----------------------------------------------------------------------
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.

Re: "External" closures, why?

Posted by alessio <al...@gmail.com>.
On Tue, Dec 1, 2015 at 9:48 PM, Winnebeck, Jason
<Ja...@windstream.com> wrote:
> 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.

So before 2.2 the cast was necessary in order to satisfy the method
signature argument-wise, with a single Object argument being the
default (and hence not requiring a cast)? Did I get that right?

RE: "External" closures, why?

Posted by "Winnebeck, Jason" <Ja...@windstream.com>.
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:alessino@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 <Ja...@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.

Re: "External" closures, why?

Posted by alessio <al...@gmail.com>.
On Tue, Dec 1, 2015 at 9:24 PM, Winnebeck, Jason
<Ja...@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

RE: "External" closures, why?

Posted by "Winnebeck, Jason" <Ja...@windstream.com>.
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)

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.

As for "function pointers" like in C, Groovy has method closures:

X x = { println "Hello, World!" }
def method = x.&xf
method()

Unlike function pointer in C, the method closure memorizes both the "this" and the method used. This allows for a very flexible "callback" or "observer" pattern in Groovy where you can pass in an interface, Closure, or a method (via a MethodClosure):

button.onClick( new ClickListener() { ... } ) //anonymous class
button.onClick { println "Clicked!" }
button.onClick this.&onOkClicked

Jason

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

On Tue, Dec 1, 2015 at 5:44 PM, Jochen Theodorou <bl...@gmx.org> wrote:
> The syntax is not new, Groovy had this kind of "attached block" since pre Groovy 1.0 times.

Alright, I did just run the code with against 2.0 (which was supposed not to support it) and it ran just fine.

But then, what does the documentation refer to when it says one can omit an explicit coercion as of 2.2?

>
> This kind of block usage w

Something is missing here.

On Tue, Dec 1, 2015 at 5:58 PM, Owen Rubel <or...@gmail.com> wrote:
> Maybe I can help a little...

Thanks, appreciated!

>
> This is especially useful if it is something like a method call that 
> only gets called once. Why create a method for it? Just use a closure. 
> :)
>
> Closures provide tons of convenience over methods. They are not meant 
> to replace them at all but act as a convenience method

In my understanding that is just a function pointer (good old C :) ) or - if one likes it better - an anonymous function or - if someone likes the Java term better :) - a lambda.

So far so good, the concept itself is not that much of a problem, the thing that I was simply wondering (and which confused the heck out of me :) ) is the choice to support mentioned form of passing the closure, which IMVHO could be utterly confusing, as the passed function is VISUALLY not part of the function call but "dangling"
somewhere near it.

Thanks again!

----------------------------------------------------------------------
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.

Re: "External" closures, why?

Posted by alessio <al...@gmail.com>.
On Tue, Dec 1, 2015 at 5:44 PM, Jochen Theodorou <bl...@gmx.org> wrote:
> The syntax is not new, Groovy had this kind of "attached block" since pre Groovy 1.0 times.

Alright, I did just run the code with against 2.0 (which was supposed
not to support it) and it ran just fine.

But then, what does the documentation refer to when it says one can
omit an explicit coercion as of 2.2?

>
> This kind of block usage w

Something is missing here.

On Tue, Dec 1, 2015 at 5:58 PM, Owen Rubel <or...@gmail.com> wrote:
> Maybe I can help a little...

Thanks, appreciated!

>
> This is especially useful if it is something like a method call that only
> gets called once. Why create a method for it? Just use a closure. :)
>
> Closures provide tons of convenience over methods. They are not meant to
> replace them at all but act as a convenience method

In my understanding that is just a function pointer (good old C :) )
or - if one likes it better - an anonymous function or - if someone
likes the Java term better :) - a lambda.

So far so good, the concept itself is not that much of a problem, the
thing that I was simply wondering (and which confused the heck out of
me :) ) is the choice to support mentioned form of passing the
closure, which IMVHO could be utterly confusing, as the passed
function is VISUALLY not part of the function call but "dangling"
somewhere near it.

Thanks again!

Re: "External" closures, why?

Posted by Owen Rubel <or...@gmail.com>.
Maybe I can help a little...

Like most things in Groovy, closures provide a convenience. They are
similar to methods but they are more 'compact' in that they can be embedded
in calls, as method variables (as their returned output is accepted as the
input for the method) , etc. They can be used places where methods can't be
used provide a level of simplicity and reducing verbosity of your code.

This is especially useful if it is something like a method call that only
gets called once. Why create a method for it? Just use a closure. :)

Closures provide tons of convenience over methods. They are not meant to
replace them at all but act as a convenience method

Anyone, Correct me if I'm wrong?

Owen Rubel
415-971-0976
orubel@gmail.com

On Tue, Dec 1, 2015 at 8:42 AM, alessio <al...@gmail.com> wrote:

> Hi Søren,
>
> thank you for the swift response. I understood that the "formal" way
> is still possible *), I am just literally puzzled as to why the syntax
> would provide for this kind of alternative in the first place.
> Maybe I am old-fashioned **) but to me this seems extremely confusing
> as it looks like a fusion of a traditional method declaration combined
> with a possibly following block statement and a pinch of a "dangling"
> anonymous function/closure/....
>
> Apologies if I may seem nitpicking, the syntax is (partially) new to
> me, but the syntax really left me bewildered (particularly because I
> have the impression such a freely dangling closure is only possible in
> THAT context and nowhere else).
>
> Thanks again :)
>
> *) From what I deduced, it only works if the method expects the
> closure as ultimate argument. In that case it can be appended outside,
> otherwise not. Would that be correct?
> **) Yes, I havent fully dived into Groovy's support for the omission
> of parenthesis and commas either yet - maybe I shouldnt :)
>
> On Tue, Dec 1, 2015 at 5:23 PM, Søren Berg Glasius <so...@glasius.dk>
> wrote:
> > Hi Alessio,
> >
> > It's not a problem to use the closure like this:
> >
> > sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle'], {
> >   // process row
> > })
> >
> > it is simply a matter of how you place your parentesees
> >
> > When you use closures with collections you would offen omit the
> parentheses
> > all together:
> >
> > collection.each {
> >    // do something with it
> > }
> >
> > but writing
> >
> > collection.each ({
> >    // do something with it
> > })
> >
> > yields the same result, but is a tiny bit more verbose
> >
> > Best regards / Med venlig hilsen,
> > Søren Berg Glasius
> >
> > Hedevej 1, Gl. Rye, 8680 Ry, Denmark
> > Mobile: +45 40 44 91 88, Skype: sbglasius
> > --- Press ESC once to quit - twice to save the changes.
> >
> > On December 1, 2015 at 17:19:07, alessio (alessino@gmail.com ) wrote:
> >
> > Hi,
> >
> > I have just started to dig into Groovy and have been mostly impressed
> > by what it offers, however when I had a look at handling database
> > calls (http://docs.groovy-lang.org/latest/html/api/groovy/sql/Sql.html)
> > I stumbled upon a rather weird syntax
> >
> > sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle']) {
> > // process row
> > }
> >
> > Usually I'd say this is a "regular" block scope but in this context it
> > was obviously a closure/function pointer/callback. It took me a while
> > to dig into this to find out that it can also be passed as second
> > argument to the method and was added in 2.2
> >
> >
> http://www.groovy-lang.org/semantics.html#_calling_a_method_accepting_a_sam_type_with_a_closure
> > https://issues.apache.org/jira/browse/GROOVY-6188 (the JSR link does
> > not work anymore)
> >
> > My question now is, why? Apparently pre-2.2 one had to cast the
> > closure to the appropriate type. But why making it possible to
> > actually define the closure outside of the respective call?
> >
> > At least for me this is HIGHLY confusing.
> >
> > Thanks
>

RE: "External" closures, why?

Posted by "Winnebeck, Jason" <Ja...@windstream.com>.
Groovy's syntax was confusing for me first as well. It looked extremely magical to me. But, now that I know it, it really enables very strong and clear DSLs and I'm happy everything is there.

In particular, Spock was wild to me. I was actually a few hours into reading about Spock before I realized it was actually Groovy code. It stretches the DSL concept so far that I honestly thought it was a separate language. I actually was almost about to drop Spock thinking I didn't want to have to learn Groovy and another "proprietary" language. In particular, I did not realize spaces were allowed in method names, and I didn't realize AST existed, which makes the following work:

Where:
a | b | c
1 | 2 | 3

And def "this is really a method"() { } is really a valid method declaration.

Spock probably took AST too far. Things like @Canonical make sense, but Spock's AST changes the meaning of the language, reusing only the syntax. That said, now that I know how Spock works and how to use it, I love it. But I love it like VIM. Both have a very high barrier to entry and secret arcane knowledge is required to perform even the most basic of tasks.

Jason

-----Original Message-----
From: alessio [mailto:alessino@gmail.com] 
Sent: Tuesday, December 01, 2015 11:42 AM
To: users@groovy.incubator.apache.org
Subject: Re: "External" closures, why?

Hi Søren,

thank you for the swift response. I understood that the "formal" way is still possible *), I am just literally puzzled as to why the syntax would provide for this kind of alternative in the first place.
Maybe I am old-fashioned **) but to me this seems extremely confusing as it looks like a fusion of a traditional method declaration combined with a possibly following block statement and a pinch of a "dangling"
anonymous function/closure/....

Apologies if I may seem nitpicking, the syntax is (partially) new to me, but the syntax really left me bewildered (particularly because I have the impression such a freely dangling closure is only possible in THAT context and nowhere else).

Thanks again :)

*) From what I deduced, it only works if the method expects the closure as ultimate argument. In that case it can be appended outside, otherwise not. Would that be correct?
**) Yes, I havent fully dived into Groovy's support for the omission of parenthesis and commas either yet - maybe I shouldnt :)

On Tue, Dec 1, 2015 at 5:23 PM, Søren Berg Glasius <so...@glasius.dk> wrote:
> Hi Alessio,
>
> It's not a problem to use the closure like this:
>
> sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle'], {
>   // process row
> })
>
> it is simply a matter of how you place your parentesees
>
> When you use closures with collections you would offen omit the 
> parentheses all together:
>
> collection.each {
>    // do something with it
> }
>
> but writing
>
> collection.each ({
>    // do something with it
> })
>
> yields the same result, but is a tiny bit more verbose
>
> Best regards / Med venlig hilsen,
> Søren Berg Glasius
>
> Hedevej 1, Gl. Rye, 8680 Ry, Denmark
> Mobile: +45 40 44 91 88, Skype: sbglasius
> --- Press ESC once to quit - twice to save the changes.
>
> On December 1, 2015 at 17:19:07, alessio (alessino@gmail.com ) wrote:
>
> Hi,
>
> I have just started to dig into Groovy and have been mostly impressed 
> by what it offers, however when I had a look at handling database 
> calls 
> (http://docs.groovy-lang.org/latest/html/api/groovy/sql/Sql.html)
> I stumbled upon a rather weird syntax
>
> sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle']) { 
> // process row }
>
> Usually I'd say this is a "regular" block scope but in this context it 
> was obviously a closure/function pointer/callback. It took me a while 
> to dig into this to find out that it can also be passed as second 
> argument to the method and was added in 2.2
>
> http://www.groovy-lang.org/semantics.html#_calling_a_method_accepting_
> a_sam_type_with_a_closure
> https://issues.apache.org/jira/browse/GROOVY-6188 (the JSR link does 
> not work anymore)
>
> My question now is, why? Apparently pre-2.2 one had to cast the 
> closure to the appropriate type. But why making it possible to 
> actually define the closure outside of the respective call?
>
> At least for me this is HIGHLY confusing.
>
> 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.

Re: "External" closures, why?

Posted by alessio <al...@gmail.com>.
Hi Søren,

thank you for the swift response. I understood that the "formal" way
is still possible *), I am just literally puzzled as to why the syntax
would provide for this kind of alternative in the first place.
Maybe I am old-fashioned **) but to me this seems extremely confusing
as it looks like a fusion of a traditional method declaration combined
with a possibly following block statement and a pinch of a "dangling"
anonymous function/closure/....

Apologies if I may seem nitpicking, the syntax is (partially) new to
me, but the syntax really left me bewildered (particularly because I
have the impression such a freely dangling closure is only possible in
THAT context and nowhere else).

Thanks again :)

*) From what I deduced, it only works if the method expects the
closure as ultimate argument. In that case it can be appended outside,
otherwise not. Would that be correct?
**) Yes, I havent fully dived into Groovy's support for the omission
of parenthesis and commas either yet - maybe I shouldnt :)

On Tue, Dec 1, 2015 at 5:23 PM, Søren Berg Glasius <so...@glasius.dk> wrote:
> Hi Alessio,
>
> It's not a problem to use the closure like this:
>
> sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle'], {
>   // process row
> })
>
> it is simply a matter of how you place your parentesees
>
> When you use closures with collections you would offen omit the parentheses
> all together:
>
> collection.each {
>    // do something with it
> }
>
> but writing
>
> collection.each ({
>    // do something with it
> })
>
> yields the same result, but is a tiny bit more verbose
>
> Best regards / Med venlig hilsen,
> Søren Berg Glasius
>
> Hedevej 1, Gl. Rye, 8680 Ry, Denmark
> Mobile: +45 40 44 91 88, Skype: sbglasius
> --- Press ESC once to quit - twice to save the changes.
>
> On December 1, 2015 at 17:19:07, alessio (alessino@gmail.com ) wrote:
>
> Hi,
>
> I have just started to dig into Groovy and have been mostly impressed
> by what it offers, however when I had a look at handling database
> calls (http://docs.groovy-lang.org/latest/html/api/groovy/sql/Sql.html)
> I stumbled upon a rather weird syntax
>
> sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle']) {
> // process row
> }
>
> Usually I'd say this is a "regular" block scope but in this context it
> was obviously a closure/function pointer/callback. It took me a while
> to dig into this to find out that it can also be passed as second
> argument to the method and was added in 2.2
>
> http://www.groovy-lang.org/semantics.html#_calling_a_method_accepting_a_sam_type_with_a_closure
> https://issues.apache.org/jira/browse/GROOVY-6188 (the JSR link does
> not work anymore)
>
> My question now is, why? Apparently pre-2.2 one had to cast the
> closure to the appropriate type. But why making it possible to
> actually define the closure outside of the respective call?
>
> At least for me this is HIGHLY confusing.
>
> Thanks

Re: "External" closures, why?

Posted by Søren Berg Glasius <so...@glasius.dk>.
Hi Alessio,

It's not a problem to use the closure like this:

sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle'], { 
  // process row 
}) 

it is simply a matter of how you place your parentesees 

When you use closures with collections you would offen omit the parentheses all together:

collection.each {
   // do something with it
}

but writing 

collection.each ({
   // do something with it
})

yields the same result, but is a tiny bit more verbose

Best regards / Med venlig hilsen,  
Søren Berg Glasius  

Hedevej 1, Gl. Rye, 8680 Ry, Denmark  
Mobile: +45 40 44 91 88, Skype: sbglasius  
--- Press ESC once to quit - twice to save the changes.

On December 1, 2015 at 17:19:07, alessio (alessino@gmail.com ) wrote:

Hi,

I have just started to dig into Groovy and have been mostly impressed
by what it offers, however when I had a look at handling database
calls (http://docs.groovy-lang.org/latest/html/api/groovy/sql/Sql.html)
I stumbled upon a rather weird syntax

sql.eachRow('select * from PROJECT where name=:foo', [foo:'Gradle']) {
// process row
}

Usually I'd say this is a "regular" block scope but in this context it
was obviously a closure/function pointer/callback. It took me a while
to dig into this to find out that it can also be passed as second
argument to the method and was added in 2.2

http://www.groovy-lang.org/semantics.html#_calling_a_method_accepting_a_sam_type_with_a_closure
https://issues.apache.org/jira/browse/GROOVY-6188 (the JSR link does
not work anymore)

My question now is, why? Apparently pre-2.2 one had to cast the
closure to the appropriate type. But why making it possible to
actually define the closure outside of the respective call?

At least for me this is HIGHLY confusing.

Thanks