[groovy-user] GVector and apply

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

[groovy-user] GVector and apply

Russel Winder
I guess there is either something wrong with the example or with the
Groovy support.  My version of the GVector example is now:

        class GVector extends java.util.Vector {
          public GVector ( ) { super ( ) }
          public void apply ( Closure c  ) { for ( i in 0 ..< size ( ) ){ this[i] = c ( this[i] ) } }
          public GVector plus ( GVector g ) {
            GVector result = new GVector ( )
            for ( i in 0 ..< size ( ) ) { result[i] = this[i] + g[i] }
            return result
          }
        }
       
        def g = new GVector ( )
        g[0] = 1
        g[1] = 2
       
        g.apply ( { item -> print item } )
       
        def h = new GVector ( )
        h[0] = 2
        h[1] = 2
       
        println ( g + h )
       
I have added the type Closure for the apply method before it didn't even
have a def so what was c bound to?

Anyway the upshot of the script is:

        12Caught: java.lang.NullPointerException: Cannot invoke method plus() on null object
                at GVector.plus(./gvectorTest.groovy:8)
                at gvectorTest.run(./gvectorTest.groovy:23)
                at gvectorTest.main(./gvectorTest.groovy)
       
which isn't exactly what I was expecting ;-)

--
Russel.
====================================================
Dr Russel Winder                +44 20 7585 2200
41 Buckmaster Road              +44 7770 465 077
London SW11 1EN, UK             [hidden email]

signature.asc (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [groovy-user] GVector and apply

tugwilson

On 3 Nov 2005, at 07:33, Russel Winder wrote:

> I guess there is either something wrong with the example or with the
> Groovy support.  My version of the GVector example is now:
>
>         class GVector extends java.util.Vector {
>           public GVector ( ) { super ( ) }
>           public void apply ( Closure c  ) { for ( i in 0 ..< size  
> ( ) ){ this[i] = c ( this[i] ) } }
>           public GVector plus ( GVector g ) {
>             GVector result = new GVector ( )
>             for ( i in 0 ..< size ( ) ) { result[i] = this[i] + g[i] }
>             return result
>           }
>         }
>
>         def g = new GVector ( )
>         g[0] = 1
>         g[1] = 2
>
>         g.apply ( { item -> print item } )

the closure { item -> print item } returns null
So this sets all the elements of g to null

>
>         def h = new GVector ( )
>         h[0] = 2
>         h[1] = 2
>
>         println ( g + h )

as each element of g is null you are adding 2 to null - you get a  
NullPointerException :)

>
> I have added the type Closure for the apply method before it didn't  
> even
> have a def so what was c bound to?

It would have been of type Object .

>
> Anyway the upshot of the script is:
>
>         12Caught: java.lang.NullPointerException: Cannot invoke  
> method plus() on null object
>                 at GVector.plus(./gvectorTest.groovy:8)
>                 at gvectorTest.run(./gvectorTest.groovy:23)
>                 at gvectorTest.main(./gvectorTest.groovy)
>
> which isn't exactly what I was expecting ;-)


Reply | Threaded
Open this post in threaded view
|

Re: [groovy-user] GVector and apply

Russel Winder
On Thu, 2005-11-03 at 07:43 +0000, John Wilson wrote:

> >         g.apply ( { item -> print item } )
>
> the closure { item -> print item } returns null
> So this sets all the elements of g to null

Hummm... maybe I should wake up before emailing.  That was fairly
obvious once pointed out :-)

--
Russel.
====================================================
Dr Russel Winder                +44 20 7585 2200
41 Buckmaster Road              +44 7770 465 077
London SW11 1EN, UK             [hidden email]

signature.asc (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [groovy-user] GVector and apply

Russel Winder
In reply to this post by tugwilson
On Thu, 2005-11-03 at 07:43 +0000, John Wilson wrote:

> > I have added the type Closure for the apply method before it didn't  
> > even
> > have a def so what was c bound to?
>
> It would have been of type Object .

Sorry I didn't phrase things properly.  There are three basic options
for declaration of apply:

apply ( c ) { . . . }
apply ( def c ) { . . . }
apply ( Closure c ) { . . . }

For me the last is preferable as trying to execute doCall on Object
seems wrong.  But what is the difference between the first two.  Both
make c of type Object.  I thought the issue was the scope of the
variable.  In the first c refers to some variable in an outer magic
Binding object whereas the latter declares a new variable scoped to the
method.  If this is correct then it could be argued that the first is
"wrong" and the latter "right".

Which do we actually want on the Web site.  This is important as the
code displayed on the Web site defines Groovy.
--
Russel.
====================================================
Dr Russel Winder                +44 20 7585 2200
41 Buckmaster Road              +44 7770 465 077
London SW11 1EN, UK             [hidden email]

signature.asc (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [groovy-user] GVector and apply

tugwilson
In reply to this post by Russel Winder

On 3 Nov 2005, at 07:47, Russel Winder wrote:

> Hummm... maybe I should wake up before emailing.  That was fairly
> obvious once pointed out :-)

I only noticed it because I've done the same myself several times:)


John Wilson
The Wilson Partnership
http://www.wilson.co.uk


Reply | Threaded
Open this post in threaded view
|

Re: [groovy-user] GVector and apply

tugwilson
In reply to this post by Russel Winder

On 3 Nov 2005, at 07:54, Russel Winder wrote:

> Sorry I didn't phrase things properly.  There are three basic options
> for declaration of apply:
>
> apply ( c ) { . . . }
> apply ( def c ) { . . . }
> apply ( Closure c ) { . . . }
>
> For me the last is preferable as trying to execute doCall on Object
> seems wrong.  But what is the difference between the first two.  Both
> make c of type Object.  I thought the issue was the scope of the
> variable.  In the first c refers to some variable in an outer magic
> Binding object whereas the latter declares a new variable scoped to  
> the
> method.  If this is correct then it could be argued that the first is
> "wrong" and the latter "right".


I wasn't active in the project when def was introduced so the  
following is an informed guess:

def solves a particular problem which is distinguishing between a  
declaration and initialisation and the assignment to an existing  
variable. This problem comes up in nested blocks and closures. It was  
an issue since the beginning of Groovy and introducing def made it  
perfect;y clear what was intended.

There are situations in which it is clear that a variable is being  
declared then def is optional:

def a = 0
def Integer i = 1
Integer j = 2

the third form is allowed as def is not required to mark the  
statement as a declaration

In the case of apply(c) it is clear that this declares c so the def  
is optional.



John Wilson
The Wilson Partnership
http://www.wilson.co.uk


Reply | Threaded
Open this post in threaded view
|

Re: [groovy-user] GVector and apply

Martin C. Martin
In reply to this post by Russel Winder


Russel Winder wrote:

>... trying to execute doCall on Object
>seems wrong.
>
This is a basic distinction between statically typed and dynamically
typed languages:  It's ok to call methods that only exist in derived
classes.  In fact, it's "typical" for most/all variables to be untyped
(i.e. of type Object), and (of course) most of the methods you call
won't be the few defined in Object.  Python doesn't even provide a way
to specify a compile-time type for a variable.  It just doesn't seem all
that useful.

Reply | Threaded
Open this post in threaded view
|

Re: [groovy-user] GVector and apply

Martin C. Martin
In reply to this post by Russel Winder
Another problem:

Russel Winder wrote:

>I guess there is either something wrong with the example or with the
>Groovy support.  My version of the GVector example is now:
>
>        class GVector extends java.util.Vector {
>          public GVector ( ) { super ( ) }
>          public void apply ( Closure c  ) { for ( i in 0 ..< size ( ) ){ this[i] = c ( this[i] ) } }
>          public GVector plus ( GVector g ) {
>            GVector result = new GVector ( )
>  
>
At this point, result is size zero.

>            for ( i in 0 ..< size ( ) ) { result[i] = this[i] + g[i] }
>  
>
Here you're assigning to elements of "result" beyond it's end.

This problem and some of your others are not Groovy-related, you'd have
the same problem in Java.

>            return result
>          }
>        }
>        
>        def g = new GVector ( )
>        g[0] = 1
>        g[1] = 2
>        
>        g.apply ( { item -> print item } )
>        
>        def h = new GVector ( )
>        h[0] = 2
>        h[1] = 2
>        
>        println ( g + h )
>        
>I have added the type Closure for the apply method before it didn't even
>have a def so what was c bound to?
>
>Anyway the upshot of the script is:
>
>        12Caught: java.lang.NullPointerException: Cannot invoke method plus() on null object
>                at GVector.plus(./gvectorTest.groovy:8)
>                at gvectorTest.run(./gvectorTest.groovy:23)
>                at gvectorTest.main(./gvectorTest.groovy)
>        
>which isn't exactly what I was expecting ;-)
>
>  
>
Reply | Threaded
Open this post in threaded view
|

Re: [groovy-user] GVector and apply

Russel Winder
On Thu, 2005-11-03 at 08:17 -0500, Martin C. Martin wrote:

> >        class GVector extends java.util.Vector {
> >          public GVector ( ) { super ( ) }
> >          public void apply ( Closure c  ) { for ( i in 0 ..< size ( ) ){ this[i] = c ( this[i] ) } }
> >          public GVector plus ( GVector g ) {
> >            GVector result = new GVector ( )
> >  
> >
> At this point, result is size zero.

It does seem that way doesn't it.

> >            for ( i in 0 ..< size ( ) ) { result[i] = this[i] + g[i] }
> >  
> Here you're assigning to elements of "result" beyond it's end.

That would appear to be the case.  But... it works.

> This problem and some of your others are not Groovy-related, you'd have
> the same problem in Java.

This would certainly fail in Java but it seems to work in Groovy.

> >            return result
> >          }
> >        }
> >        
> >        def g = new GVector ( )
> >        g[0] = 1
> >        g[1] = 2
> >        
> >        g.apply ( { item -> print item } )

This needs to be   g.apply ( { item -> print item ; item } )

as John pointed out.

> >        def h = new GVector ( )
> >        h[0] = 2
> >        h[1] = 2
> >        
> >        println ( g + h )

Executing this script gives:

12[3, 4]

so either assigning to a non-existent indexed location in a Vector turns
out to be OK after all or Groovy is broken.  Or perhaps there is a third
path ;-)
 
--
Russel.
====================================================
Dr Russel Winder                +44 20 7585 2200
41 Buckmaster Road              +44 7770 465 077
London SW11 1EN, UK             [hidden email]

signature.asc (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [groovy-user] GVector and apply

Martin C. Martin


Russel Winder wrote:
On Thu, 2005-11-03 at 08:17 -0500, Martin C. Martin wrote:

  
       class GVector extends java.util.Vector {
         public GVector ( ) { super ( ) }
         public void apply ( Closure c  ) { for ( i in 0 ..< size ( ) ){ this[i] = c ( this[i] ) } }
         public GVector plus ( GVector g ) {
           GVector result = new GVector ( )
 

      
At this point, result is size zero.
    

It does seem that way doesn't it.

  
           for ( i in 0 ..< size ( ) ) { result[i] = this[i] + g[i] }
 
      
Here you're assigning to elements of "result" beyond it's end.
    

That would appear to be the case.  But... it works.
  
"Most remarkable!"  ;)  Does Groovy add a "putAt()" function to Vector (and other Lists) that resizes it if need be?

- Martin

12