This is the mail archive of the kawa@sources.redhat.com mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: question about "object"


Per Bothner writes:
 > Doug Orleans <dougo@ccs.neu.edu> writes:
 > 
 > > Unfortunately, two lists which are equal? might not have the same hash 
 > > code:
 > 
 > Could you try the cvs version?  It seems to work there.

Will do.

 > > Although it would be nice if hash codes were in fact equal for equal
 > > lists,
 > 
 > It is more than nice - it is required.

Oh, hm.  Good point!

 > > I still need to override the equals method because the keys are
 > > actually lists of objects which might be circular data structures
 > > (which causes equal? to go into an infinite loop).
 > 
 > That may be more difficult.  In general, it might be quite expensive
 > to handle self-referential structures  correctly.

Well, in this case I only need to go to depth 1, i.e. (every eq? l1 l2).
I agree, in general it would be much trickier.

 > Did you verify that:
 >   (equal? (hashtable-key '(x y z)) (hashtable-key '(x y z)))
 > and
 >   (invoke (hashtable-key '(x y z) 'equals (hashtable-key '(x y z))))

Yes to the latter (see the command at prompt #|kawa:25|# in my
previous mail).  However, I just figured out the problem, thanks to
reflection:

#|kawa:76|# (invoke (invoke (hashtable-key '(1 2 3)) 'getClass) 'getDeclaredMethod "hashCode" #!null)
public java.lang.Object object.hashCode()

Wrong return type!  After looking more closely at the "object" syntax,
I noticed there's no "::" when declaring the return type; so I tried
this:

#|kawa:77|# (invoke (invoke (object () ((foo) int 3)) 'getClass) 'getDeclaredMethod "foo" #!null)
<stdin>:77:2: warning - no possibly applicable method `getDeclaredMethod' in java.lang.Class
public gnu.math.IntNum object.foo()

(Not sure what the deal is with that warning message...)

Then I realized that "int" meant scheme ints, while the proper name
for Java ints was "<int>":

#|kawa:78|# (invoke (invoke (object () ((foo) <int> 3)) 'getClass) 'getDeclaredMethod "foo" #!null)
<stdin>:78:2: warning - no possibly applicable method `getDeclaredMethod' in java.lang.Class
public int object.foo()

Voila!  So here's the correct version of hashtable-key:

(define (hashtable-key list)
  (object ()
    ((hashCode) <int>
     (list-hash list))
    ((equals obj :: <java.lang.Object>) <boolean>
     (same-list? list (invoke obj 'getList)))
    ((getList)
     list)))

#|kawa:89|# (invoke ht 'put (hashtable-key '(x y z)) 'xyz)
#!null
#|kawa:90|# (invoke ht 'get (hashtable-key '(x y z)))
xyz

Now, there's still a minor problem-- this definition causes a warning:

<stdin>:97:7: warning - no method `getList' in java.lang.Object

Unfortunately, since it's an anonymous class, there's no way to cast
the "obj" parameter to the right type before calling "getList" because
we don't know the name of the class.  (The same problem would occur in 
Java, except it would be an error, not just a warning...)  I guess I
need to figure out how to define a module now.  (Or is "define-class"
in the CVS version?)

Anyway, sorry for spamming the list with a newbie user error.  But
it's a good example of how easy debugging is with reflection and an
interactive environment!

--dougo@ccs.neu.edu


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]