public inbox for kawa@sourceware.org
 help / color / mirror / Atom feed
* [patch] set setter for array-ref to array-set!
@ 2015-03-01  4:12 Jamison Hope
  2015-03-02 20:09 ` Per Bothner
  0 siblings, 1 reply; 5+ messages in thread
From: Jamison Hope @ 2015-03-01  4:12 UTC (permalink / raw)
  To: kawa@sourceware.org list

[-- Attachment #1: Type: text/plain, Size: 264 bytes --]

Here's a patch which sets the setter property of array-ref to array-set!.

(let ((a (make-array
            (shape 4 5 4 5 4 5))))
   (set! (array-ref a 4 4 4) "huuhkaja")
   (array-ref a 4 4 4))

=> "huuhkaja"

--
Jamison Hope
The PTR Group
www.theptrgroup.com



[-- Attachment #2: array-ref-setter.patch --]
[-- Type: application/octet-stream, Size: 922 bytes --]

Index: gnu/kawa/functions/ArrayRef.java
===================================================================
--- gnu/kawa/functions/ArrayRef.java	(revision 8360)
+++ gnu/kawa/functions/ArrayRef.java	(working copy)
@@ -8,6 +8,9 @@
 public class ArrayRef extends ProcedureN
 {
   public static final ArrayRef arrayRef = new ArrayRef();
+    static {
+        arrayRef.setSetter(ArraySet.arraySet);
+    }
 
   public static Object arrayRef(Array array, Sequence index)
   {
Index: gnu/kawa/functions/ChangeLog
===================================================================
--- gnu/kawa/functions/ChangeLog	(revision 8360)
+++ gnu/kawa/functions/ChangeLog	(working copy)
@@ -1,3 +1,7 @@
+2015-02-28  Jamison Hope  <jrh@theptrgroup.com>
+
+	* ArrayRef.java (arrayRef): Set setter property to ArraySet.arraySet.
+
 2015-02-28  Per Bothner  <per@bothner.com>
 
 	* CompileMisc.java: Remove unneeded call to code.emitTryEnd.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch] set setter for array-ref to array-set!
  2015-03-01  4:12 [patch] set setter for array-ref to array-set! Jamison Hope
@ 2015-03-02 20:09 ` Per Bothner
  2015-03-05  7:54   ` Jamison Hope
  0 siblings, 1 reply; 5+ messages in thread
From: Per Bothner @ 2015-03-02 20:09 UTC (permalink / raw)
  To: kawa



On 02/28/2015 08:11 PM, Jamison Hope wrote:
> Here's a patch which sets the setter property of array-ref to array-set!.
>
> (let ((a (make-array
>              (shape 4 5 4 5 4 5))))
>     (set! (array-ref a 4 4 4) "huuhkaja")
>     (array-ref a 4 4 4))
>
> => "huuhkaja"

Thanks - I checked this in.

I also checking support for using "function-call notation"
like we already do for java.util.List and Java arrays:

|kawa:1|# (! ar (make-array (shape 2 4 2 4) -1))
#|kawa:2|# ar
#2a((-1 -1) (-1 -1))
#|kawa:3|# (set! (ar 3 2) 32)
#|kawa:4|# ar
#2a((-1 -1) (32 -1))
#|kawa:5|# (ar 3 3)
-1

There is no inlining or other optimization yet for
either notation.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch] set setter for array-ref to array-set!
  2015-03-02 20:09 ` Per Bothner
@ 2015-03-05  7:54   ` Jamison Hope
  2015-03-06 19:15     ` Per Bothner
  0 siblings, 1 reply; 5+ messages in thread
From: Jamison Hope @ 2015-03-05  7:54 UTC (permalink / raw)
  To: kawa@sourceware.org list

On Mar 2, 2015, at 3:08 PM, Per Bothner <per@bothner.com> wrote:

> On 02/28/2015 08:11 PM, Jamison Hope wrote:
>> Here's a patch which sets the setter property of array-ref to array-set!.
>> 
>> (let ((a (make-array
>>             (shape 4 5 4 5 4 5))))
>>    (set! (array-ref a 4 4 4) "huuhkaja")
>>    (array-ref a 4 4 4))
>> 
>> => "huuhkaja"
> 
> Thanks - I checked this in.
> 
> I also checking support for using "function-call notation"
> like we already do for java.util.List and Java arrays:
> 
> |kawa:1|# (! ar (make-array (shape 2 4 2 4) -1))
> #|kawa:2|# ar
> #2a((-1 -1) (-1 -1))
> #|kawa:3|# (set! (ar 3 2) 32)
> #|kawa:4|# ar
> #2a((-1 -1) (32 -1))
> #|kawa:5|# (ar 3 3)
> -1
> 
> There is no inlining or other optimization yet for
> either notation.

What do you think about doing similar things for hash tables?

This works (even though RNRS hashtable-ref takes a third argument):

(import (rnrs hashtables))
(set! (setter hashtable-ref) hashtable-set!)

(define h (make-eq-hashtable))
(set! (hashtable-ref h 'year) 2015)
h => {year=2015}


It seems like function call notation would be nice for java.util.Map
instances, too:

(set! (h k) v) => (h:put k v)
(h k) => (h:get k)

Thoughts?  Part of a GSoC project, perhaps?

--
Jamison Hope
The PTR Group
www.theptrgroup.com



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch] set setter for array-ref to array-set!
  2015-03-05  7:54   ` Jamison Hope
@ 2015-03-06 19:15     ` Per Bothner
  2015-03-07  6:30       ` Jamison Hope
  0 siblings, 1 reply; 5+ messages in thread
From: Per Bothner @ 2015-03-06 19:15 UTC (permalink / raw)
  To: kawa



On 03/04/2015 11:54 PM, Jamison Hope wrote:
> What do you think about doing similar things for hash tables?
>
> This works (even though RNRS hashtable-ref takes a third argument):
>
> (import (rnrs hashtables))
> (set! (setter hashtable-ref) hashtable-set!)
>
> (define h (make-eq-hashtable))
> (set! (hashtable-ref h 'year) 2015)
> h => {year=2015}

It's a little ugly because of the weirdness with the default parameter -
i.e. that (hashtable-ref h 'year) is not a valid call, even after the set!.
Plus it doesn't make the code any more compact or readable.

> It seems like function call notation would be nice for java.util.Map
> instances, too:
>
> (set! (h k) v) => (h:put k v)
> (h k) => (h:get k)
>
> Thoughts?  Part of a GSoC project, perhaps?

Too small for a GSoC project.

Using function call notation seems reasonable, but I think I had some concerns
I can't quite remember.  One minor issue is the "conflict" with colon notation
when it comes to string or symbol keys.  Should we prefer:
   (my-table "foo")
or:
   my-table:foo
That issue is probably a distraction.

Another issue to note: If we support function call notation, I'd like
it to work for any java.util.Map, not just those returned by make-hash-table
or make-hashtable.

Finally there is the issue of defaults.  If a key isn't in my-table what should
be the result of this?
   (my-table key)
Arguably this should throw an exception as key isn't in its domain.
The other alternative is to return #!null, for simplicity and compatibility
with the Java Map interface.

My inclination would be to throw an exception, and also introduce:
   (my-table key default: default-value)
If default-value is #!null this should be compiled to a call to the Map get routine.
If default-value is non#!null it should be compiled to the getOrDefault method
if either the target is Java 8 or if my-table is known to be a sub-class of
AbstractHashTable; otherwise we call a static helper method.

(Of course if my-table isn't known to be a Map at compile-time we have to check
if it's a Map at run-time.)

Comments?
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch] set setter for array-ref to array-set!
  2015-03-06 19:15     ` Per Bothner
@ 2015-03-07  6:30       ` Jamison Hope
  0 siblings, 0 replies; 5+ messages in thread
From: Jamison Hope @ 2015-03-07  6:30 UTC (permalink / raw)
  To: kawa@sourceware.org list

On Mar 6, 2015, at 2:15 PM, Per Bothner <per@bothner.com> wrote:

> On 03/04/2015 11:54 PM, Jamison Hope wrote:
>> What do you think about doing similar things for hash tables?
>> 
>> This works (even though RNRS hashtable-ref takes a third argument):
>> 
>> (import (rnrs hashtables))
>> (set! (setter hashtable-ref) hashtable-set!)
>> 
>> (define h (make-eq-hashtable))
>> (set! (hashtable-ref h 'year) 2015)
>> h => {year=2015}
> 
> It's a little ugly because of the weirdness with the default parameter -
> i.e. that (hashtable-ref h 'year) is not a valid call, even after the set!.
> Plus it doesn't make the code any more compact or readable.

The mandatory default parameter does make it weird, yeah.  It's kind of
unfortunate that it breaks symmetry with the other TYPE-ref / TYPE-set!
pairs.

>> It seems like function call notation would be nice for java.util.Map
>> instances, too:
>> 
>> (set! (h k) v) => (h:put k v)
>> (h k) => (h:get k)
>> 
>> Thoughts?  Part of a GSoC project, perhaps?
> 
> Too small for a GSoC project.

That's why I said "part of".  Or perhaps as a small introductory project
for a student who wants to get a taste of Kawa hacking before the summer.

> Using function call notation seems reasonable, but I think I had some concerns
> I can't quite remember.  One minor issue is the "conflict" with colon notation
> when it comes to string or symbol keys.  Should we prefer:
>  (my-table "foo")
> or:
>  my-table:foo
> That issue is probably a distraction.

My vote would be for (my-table "foo"), since I tend to think of hash tables
as being like arrays with arbitrary objects as indices.  It would work with
non-string/symbol keys, too, and with non-literal keys.  If my-table is the
Map {1=I, 5=V, 10=X}, then

(let ((a 5)) (my-table a)) => "V"

Also note that C++ std::unordered_map uses operator[] for array-like syntax,
as in
 map["key"] = value;

> Another issue to note: If we support function call notation, I'd like
> it to work for any java.util.Map, not just those returned by make-hash-table
> or make-hashtable.

Yes, absolutely.

> Finally there is the issue of defaults.  If a key isn't in my-table what should
> be the result of this?
>  (my-table key)
> Arguably this should throw an exception as key isn't in its domain.
> The other alternative is to return #!null, for simplicity and compatibility
> with the Java Map interface.

I think I would prefer for it to return #!null.  Now that Kawa treats #!null
as false, this would not only be compatible with the Java Map API, it would
also be consistent with how assoc works for association lists and SRFI-1's
find works for regular lists.

> My inclination would be to throw an exception, and also introduce:
>  (my-table key default: default-value)
> If default-value is #!null this should be compiled to a call to the Map get routine.
> If default-value is non#!null it should be compiled to the getOrDefault method
> if either the target is Java 8 or if my-table is known to be a sub-class of
> AbstractHashTable; otherwise we call a static helper method.
> 
> (Of course if my-table isn't known to be a Map at compile-time we have to check
> if it's a Map at run-time.)

I like that.  Are there any other examples of having a keyword in function-call
notation (other than actual functions)?  Maybe also support a throw:

(my-table key throw: bool)
If bool is true, then throw an exception if key is not in my-table.
If bool is false, same as (my-table:get key) (i.e. the value or #!null).


It might also be nice to have a syntax for hash table literals.  Racket has
#hash(), #hasheqv(), and #hasheq(), we could do something like that, maybe with
#{} as sugar for #hash()?


So putting all these ideas together, we might have something like:

(define h1 #{(year . 2015) (bttf . ii) (car . delorean)})

(map h1 '(car truck year)) => (delorean #!null 2015)

(define h2 (java.util.HashMap))
(set! (h2 'apple) "red")

(cond ((h2 'apple) => (lambda (c) &{apples are &[c]}))) => "apples are red"

(h2 'banana default: "yellow") => "yellow"
(h2 'orange throw: #t) => exception

--
Jamison Hope
The PTR Group
www.theptrgroup.com



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-03-07  6:30 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-01  4:12 [patch] set setter for array-ref to array-set! Jamison Hope
2015-03-02 20:09 ` Per Bothner
2015-03-05  7:54   ` Jamison Hope
2015-03-06 19:15     ` Per Bothner
2015-03-07  6:30       ` Jamison Hope

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).