(1) Mostly the point of canonical=: boxopen was that I liked the name
better, for this context. I did consider that it might be good to have
a different concept of canonical, but that's probably going to get you
into code changes anyways (because canonical names will probably be
different from canonical values - for example, it might make a lot of
sense to enforce that names are always rank 1 literals, but enforcing
that kind of thing on values probably is not going to be what you
want).

(2) One point of having the i. behavior for not found values is so you
can do stuff like this:

   (keys i. key) { values;'not found'

I added a compress onto that not found value, in my hashGet
implementation, mostly because I thought that that might be more
efficient (but I didn't benchmark so I don't actually know if the
extra complexity was useful). In other words, the result line would
work just fine if it had been phrased  j { ({:y),<'not found'

Anyways ...  an expression like

   _1 { values

also gets the last value in the list. So, hypothetically speaking, a
not found index of -1 would satisfy this purpose. But that brings us
to the other reason for the current behavior: it throws an error if
you fail to supply a not found value.

(3) I used an e. instead of an = so the code would work when I
specified multiple keys and values. Examples of this kind if thing
include:  ('a';'bb') hashGet test3 or ('a';'bb') (7;8) hashSet test4

(4) The reason I put the collection on the right is because I thought
that that would be nicer if you chain several hash statements
together. Like this, maybe:

   'bb' 17 hashSet 'a' 'Aye' hashSet 'a' 13 hashSet emptyHash

(5) "these things": keys and values.

(6) If you want to have a J routine modify something specified as an
argument, it's usually best to pass a globally valid name for that
thing as its argument. And that's what I'd do if I needed that here.
(That said, iIf you don't want the name to be globally valid, you
probably should be using locales.)

Thanks,

-- 
Raul


On Tue, Dec 5, 2017 at 12:51 PM, Andrew Dabrowski <[email protected]> wrote:
> That's nice, thanks.  Comments/questions below.
>
>
> On 12/04/2017 02:42 PM, Raul Miller wrote:
>>
>> If you're really going to use this one item at a time, you can greatly
>> increase average performance of deletes by deferring them for later
>> (for example). Similarly, you can avoid some overhead by implementing
>> that as an object.
>>
>> That said, here's a more concise implementation:
>>
>> emptyHash=: i.2 0
>
> I didn't know you could define an array in which one dimension is 0, that's
> useful.
>>
>> canonical=: boxopen
>
> what's the point of this?  So you change the canonical form easily later?
>>
>>
>> hashSet=:1 :0
>> :
>>    j=. ({.y) i. x=. canonical x
>
> I was afraid that since boxed are treated as atoms that it would be
> impossible to test for equality of their contents without unboxing them; I
> should have checked. :-[
>>
>>    n=.-.o=. j<{:$y
>>    (({.y),n#x),:((o#m) (o#j)} {:y),n#m=. canonical m
>> )
>
> So /that's/ the idiomatic way of dealing with simple conditionals, cool.
>>
>>
>> hashGet=:4 :0
>>    j=. ({.y) i. canonical x
>>    b=. +./j={:$y
>>    j { ({:y),b#<'not found'
>> )
>
> And another trick for dealing with conditionals, nice.
>
> Btw, what's the rationale for having  i. return #list in the case the
> element is not found?  Wouldn't it be easier if it returned _1, as many
> other languages do?
>>
>>
>> hashDel=:4 :0
>>    (-.({.y) e. canonical x) #"1 y
>> )
>
> Why did you use e. here rather than =?
>>
>> As you can see, I made a few changes to your interface.
>
> Is it more J-like to have the collections on the right?
>>
>> If you're not
>> going to support setting and selecting multiple values, you should
>> think about using variables instead.
>
> I don't understand what you mean.  Use variables as opposed to a tacit
> definition?
>>
>>
>> On the other hand, if there's actual values to forming lists of these
>> things, leaving things boxed might make sense.
>
> "these things"?
>
> One thing that still bothers me: I would prefer to have the hash functions
> update the hash value rather than having to write
>
> test =: 'ccc' (1,2,3) hashSet test
>
> Is it possible to write a function that changes the value of one of its
> arguments?  Since J is a functional language that passes arguments by value
> rather than reference I'm guessing not.
>
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to