User defined autovivification

2005-08-28 Thread Yuval Kogman
Today I wrote some perl 5 code that looked like this:

my %index_by_x;
my %index_by_y;
my %index_by_z;

foreach my $thing (@things){
( $index_by_x{$thing-x_value} ||= 
Set::Object-new)-insert($thing);
( $index_by_y{$thing-y_value} ||= 
Set::Object-new)-insert($thing);
( $index_by_z{$thing-z_value} ||= 
Set::Object-new)-insert($thing);
}

I feel this code is pretty unreadable. Luke and I tossed some ideas
for how this should look in perl 6:


from #perl6:

class Foo will autovivify { Foo.new } {
...
}

my Foo %hash;

OR

my %hash will autovivify { Foo.new };

and then:

%hashkey_that_doesn't_exist.moose; # works

or with my code:

my mk_set_object = { Set::Object.new }

my %index_x will autovivify(mk_set_object);
my %index_y will autovivify(mk_set_object);
my %index_z will autovivify(mk_set_object);

or

my class ViviSet will autovivify { $?CLASS.new }

my ViviSet %index_x;
my ViviSet %index_y;
my ViviSet %index_z;

and then

for @things - $thing {
$index_x{ $thing.x_value }.insert($thing);  
$index_y{ $thing.y_value }.insert($thing);  
$index_z{ $thing.z_value }.insert($thing);  
}

which makes the 'x_value' etc calls much more obvious, and thus good
for readability.

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /methinks long and hard, and runs away: neeyah!!!



pgpT6fmyMD2Sl.pgp
Description: PGP signature


Re: User defined autovivification

2005-08-28 Thread Yuval Kogman
On Sun, Aug 28, 2005 at 05:56:58 -0400, David Storrs wrote:
 While I think your P6 code is great, I don't feel you're comparing  apples to 
 apples.  In all your P6 examples you effectively break the  autovivify step 
 out 
 from the other steps.  You can do that in P5 too:

To me the code below isn't broken up - it still happens in the same
loop, at the same level.

I'd like to feel like i'm describing how this hash should look
like, and from then on to let the the values pop up as necessary.

  foreach my $thing (@things){
  $index_by_x{$thing-x_value} ||= Set::Object-new;
  $index_by_y{$thing-y_value} ||= Set::Object-new;
  $index_by_z{$thing-z_value} ||= Set::Object-new;
 
  $index_by_x{$thing-x_value}-insert($thing);
  $index_by_y{$thing-y_value}-insert($thing);
  $index_by_z{$thing-z_value}-insert($thing);
  }

This oranges that I think perl 6 should give me allow me to say:

foreach my $thing (@things) {
$index_by_x{$thing-x_value}-insert($thing)
}

Since earlier i said this is an array of sets and now i'm saying
this is how i populate the sets.

In perl 5 it isn't possible. I've got to say here are some things,
put them in this set, and if the set is not there, make a new one.
That's exactly what I would like to change =)

 IMO, this would be even clearer:
 
  foreach my $thing (@things){
  my($x,$y,$z) = ($thing-x_value, $thing-y_value, $thing- z_value);
 
  $index_by_x{$x} ||= Set::Object-new;
  $index_by_y{$y} ||= Set::Object-new;
  $index_by_z{$z} ||= Set::Object-new;
 
  $index_by_x{$x}-insert($thing);
  $index_by_y{$y}-insert($thing);
  $index_by_z{$z}-insert($thing);
  }

This is a pet peeve of mine.  For some reason  I really really hate
it when something is referred to more than once, when there is
lookup involved.

I personally feel that

($index_by_z{$thing-z_value} ||= Set::Object-new)-insert($thing)

is actually cleaner than this, but that might just
be me.

Furthermore, it doesn't change the semantics:

this is an hash of sets
...
this is what a set contains

vs.

this is a hash
...
if there is no set make one, and this is what a set contains

but just the syntax.

 This has the advantage of being very nonmagical, keeping code  together, and 
 avoiding AAAD.

Arguably for plain container types autovivification is semantically
safe, at least in my opinion. I would do this for weird things (for
example, autovivification should not know the key it's autovivifying
- if you want to go that far, just tie the structure).

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me dodges cabbages like macalypse log N: neeyah!



pgpHK8KDbxcSu.pgp
Description: PGP signature