problem during calling method from closure

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

problem during calling method from closure

Mariusz W
Hi,
This code should work in Groovy? I get an error as below, I think that I should change something with delegate.

groovy.lang.MissingMethodException: No signature of method: ideaGroovyConsole.foo() is applicable for argument types: () values: []

-------------
class Boo {
    def boo() {throw new UnsupportedOperationException("should override")}
    def foo() { println "foo"}
}

def a = [boo : {
    foo()
}] as Boo

a.boo()

-------------

Regards,
Mariusz

Reply | Threaded
Open this post in threaded view
|

Re: problem during calling method from closure

Anton Shepelev
Mariusz W:

> class Boo {
>     def boo() {throw new UnsupportedOperationException("should override")}
>     def foo() { println "foo"}
> }
>
> def a = [boo : {
>     foo()
> }] as Boo
>
> a.boo()

As far as I can see (which is not a great distance away from
my nose), you are trying to construct an object with the
boo() method redefined to call the foo() method of the
parent class. I believe your code is incorrect at least
becuause the foo() method is unavailable at the point of
construction. You cannot refer to the method of an object
that has not yet been constructed.

Reply | Threaded
Open this post in threaded view
|

Re: problem during calling method from closure

OCsite
Anton,

...You cannot refer to the method of an object that has not yet been constructed.

As a matter of fact, you can. This darned Java “method-calling” lingo is terribly misleading; we definitely should have sticked with Alan Kay's “message-sending”, and there would be much less misunderstandings and problems today.

Anyway, Groovy (just like any other at least half-decent language) supports late-binding, which means you can essentially “call” anything of anything, and the dispatcher at the runtime would do its best to find the proper method and call it. Try e.g.,

class Foo {
   static foo0() { println "foo0"}
   static foo1() { println "foo1"}
}
Foo.metaClass.static."foo${1+1}"={ -> println "even this works OK!" }
3.times { Foo."foo$it"() }

The problem with the original code

def a = [boo : {
   foo()
}] as Boo

is — precisely as Mariusz presumed — that the closure's delegate/owner/this is the script object, not a. Alas, I can't see any elegant way to fix the problem; about the best I could think of is

def block={ foo() }
def a=[boo: block] as Boo
block.delegate=a

which should work as expected.

All the best,
OC


On 14 Oct 2020, at 17:12, Anton Shepelev <[hidden email]> wrote:

Mariusz W:

class Boo {
   def boo() {throw new UnsupportedOperationException("should override")}
   def foo() { println "foo"}
}

def a = [boo : {
   foo()
}] as Boo

a.boo()

As far as I can see (which is not a great distance away from
my nose), you are trying to construct an object with the
boo() method redefined to call the foo() method of the
parent class. I believe your code is incorrect at least
becuause the foo() method is unavailable at the point of
construction. You cannot refer to the method of an object
that has not yet been constructed.


Reply | Threaded
Open this post in threaded view
|

Re: problem during calling method from closure

Anton Shepelev
OCsite:

> As a matter of fact, you can. This darned Java "method-
> calling" lingo is terribly misleading;

It is not the Java lingo, but the standard and most
intuitive teminology.

> we definitely should have sticked with Alan Kay's
> "message-sending", and there would be much less
> misunderstandings and problems today.

I fear this message-passing approach even further from
normal proceudural prgramming that conventinal OO languages
and would therefore be even more confusing and unintuitive.

> Anyway, Groovy (just like any other at least half-decent
> language) supports late-binding, which means you can
> essentially "call" anything of anything, and the
> dispatcher at the runtime would do its best to find the
> proper method and call it.

Why do you think a decent language should support late
binding?  Some of the most decend languages that I
know -- Pascal and Modula -- do not have it. They exemplify
a great compromise between human intuitiveness and closeness
to the hardware. Ivoking proceudres and passing strongly
type values to them is a very simple and clear concept,
reflecting the human's way of thinking about separting a
difficult task into many simple ones.

> Try e.g.,
>
> class Foo {
>    static foo0() { println "foo0"}
>    static foo1() { println "foo1"}
> }
> Foo.metaClass.static."foo${1+1}"={ -> println "even this works OK!" }
> 3.times { Foo."foo$it"() }

This is black magic to me. I will try to stick with the
simple procedurla approach with Groovy as well as I can.

> The problem with the original code
> [...]

Thank for helping Mariusz.  Can you please forward your
reply to his address?  I do not see his address neither via
Gmane nor via the mailing-list archive.

MG
Reply | Threaded
Open this post in threaded view
|

Re: problem during calling method from closure

MG
On 15/10/2020 13:03, Anton Shepelev wrote:

>
>> we definitely should have sticked with Alan Kay's
>> "message-sending", and there would be much less
>> misunderstandings and problems today.
> I fear this message-passing approach even further from
> normal proceudural prgramming that conventinal OO languages
> and would therefore be even more confusing and unintuitive.
>

It is not an approach per se, but just terminology.

And when coming from Assembler/C/C++, like I do, it is a very confusing
one: At the end of the day, it is always just about pushing the
arguments on the stack and picking the subroutine address to which the
CPU shall branch, whether that address selection is static (and can
therefore be done at compile time), virtual (i.e. based on the object
the function is called for, which requires a (quick and simple) virtual
function table lookup for the object's class at runtime), dynamic (i.e.
based on the object and the argument types on the stack, like Groovy
does), or completely custom implemented in the language itself (as can
be done in Groovy).

It is never about passing messages from one object to the other, which
to me implies creating messaging objects, which are being put into a
queue for asynchronous processing by the receiving object (possibly with
prioritization, ...), and maybe being sent over a network connection,
etc. So a much more heavy & slower mechanism than what actually takes place.

Of course one often times finds logical/natural what one first
encountered, but keeping that in mind, from what lies underneath it,
calling it a method call with passed arguments still makes the most
sense to me.

Cheers,
mg




Reply | Threaded
Open this post in threaded view
|

Re: problem during calling method from closure

Anton Shepelev
MG about Alan Kay's "message passing":

> It is not an approach per se, but just terminology.

Lest I annoy the list administrators by continuing this off-
topic disussion, I will confine my reply to the remark that
Kay's concept of message passing is not mere terminology. It
is also more that just an approach -- it is a full-fledged
paradigm, alghough OCsite may not have meant it that way
when he mentioned it. Thanks for sympathy.

MG
Reply | Threaded
Open this post in threaded view
|

Re: problem during calling method from closure

MG
Hi Anton,

could you please point out to me the concepts you mention in a private
email ?
It still seems to me that what I said was right, see for instance:
https://wiki.c2.com/?AlanKaysDefinitionOfObjectOriented

Cheers,
mg

(Many of these topics are quite old, and things which are no big deal
now definitely were back then, such as the fact that C++ is not a TRUE
OO language, since calls are only virtual if the method carries that
explicit keyword  - a useless design decision from my experience, yes (I
remember trying to find a case where non-virtual calls actually gave a
performance advantage in my C++ game engine back in 2000, and just could
not construct a real world example), but at the same time not that big a
deal in practice (why the much younger language of  C# uses the same
concept remains puzzling, though.))


On 15/10/2020 20:16, Anton Shepelev wrote:

> MG about Alan Kay's "message passing":
>
>> It is not an approach per se, but just terminology.
> Lest I annoy the list administrators by continuing this off-
> topic disussion, I will confine my reply to the remark that
> Kay's concept of message passing is not mere terminology. It
> is also more that just an approach -- it is a full-fledged
> paradigm, alghough OCsite may not have meant it that way
> when he mentioned it. Thanks for sympathy.
>