[Israel.pm] Perl Advocacy

Gaal Yahas gaal at forum2.org
Thu Dec 30 09:38:18 PST 2004


david istermann wrote:

> I'm not telling you that they should be unified. Nor hashes should be
> actually implemented with an array $myhash[1] = ($hashkey,
> $hashvalue). That would be plain wrong. I'm just saying you should be
> able to use the same language constructs for both of them.

And I agree that some polymorphism is a good thing. It doesn't always
work, though, when the things being handled are too different.

 > See the example of delete(). Of course, Gaal, "delete for hashes and
 > arrays is not 100% equivalent" - but it does what is asked for - delete
 > an entry! If you want you can consider the internal of that function (it
> does not always shrink the array, it rebuilds the hash table etc etc),
> but if you don't want to, you simply use it.

But don't you see that your expectations about "does what is asked
for" can be different from mine?

>>>while ( ($key, $val) = each(%myhash) ) {...}   # $key is a string
>>>while ( ($key, $val) = each(@myarray) ) {...}   # $key is an integer
>>
>>You want $key in the second line to be the index? 1, 2, 3 etc.?
> 
> Exactly!
> 
> 
>>Then write the almost equivalent
>>    for my $key (0 .. $#myarray) {
>>        my $val = $myarray[$key];
>>        ...
>>    }
> 
> And write the following for the hash:
>    for my $key (keys %myhash) {
>       my $val = $myhash{$key};
>       ...
>    }
> 
> Cool! We don't need the each() function! Then why the hell is it
> present in the language?! 1 off. Why is there 'foreach' if it's just
> an alias to 'for'? Another 1 off. We could shrink Perl's core
> namespace by half this way...

Well yes; but *usually* you don't need both the index and the
element in array iterations.

My way of looking at it is that in an array, the index is implicit;
it isn't *data*. And yet elements do have *position*. That row of
people over there, each standing on a tile of his own:

@suspects = qw( Hockney McManus Fenster Keaton Verbal );

Sure, the first one is Hockney. But his relationship with his
place is sorta incidental. Not unimportant, but the tile he is
standing on is just a tile for a person.

On the other hand, when there's a more meaningful relationship,
you have a map, an *associative* array: a hash.

      %team = (
          'explosives' => 'Hockney',
          'entry man'  => 'McManus',
          'humor'      => 'Fenster',
          'mastermind' => 'Keaton',
          'con man'    => 'Verbal',
      );

You can ask of a hash, "who is my entry man?", and get a result.
In most cases, *both the result and the question itself are
applicatively significant*, whereas numerical index are (once
again, usually) artificial devices meant to keep significant
data in line.

>>>foreach $key (@myarray) {...}
>>>foreach $key (%myhash) {...}
>>
>>Already works. Alternates keys and values.
> 
> Why should it alternate keys and values for a HASH, and don't do the
> same for an ARRAY? If you don't read the docs carefully, you'd expect
> it to work the same way for both data types, don't you?

In my interpretation the values are interesting as data, and so are
the keys. The language answer is that it alternates keys and values
because a hash in list context is that list. This, by the way, is
what allows you to build up a hash from a list.

      %squares = map { $_ => $_ ** 2 } 1 .. 10

It would be *silly* to require all arrays to be built that way,
becuase the indices *have* to be rising integers.

      # Boring!
      @suspects = qw ( 0 Hockney 1 McManus 2 Fenster 3 Keaton 4 Verbal );

 > Actually, more tickling question is why
>    @contents = values @myarr;
> is not available in the language? I admit, having keys() for an array
> is a bit strange - but there are cases when you want simply the list
> of values() .

      @contents = @myarr;

This is just a copy.

>>>foreach ($key, $val) (@myarray) {...}
>>
>>I don't understand what you want to happen here in the array case.
> 
> 
> call it $index if you wish. Should you never want the index of the
> entries in your array? It should be a shortcu to doing:
>    for (my $key = 0; $key < $#myarray; $key ++) { my $val =
> $myarray[$key]; ... }
> - or -
>    for my $key (0 .. $#myarray - 1) { my $val = $myarray[$key]; ...}
> Look how much typing you save yourself !

Look, it's well-known that you can create a compression scheme that
in the best case compresses a terabyte of data into one bit. Just
have it emit '1' if the input is that particular terabye of data;
or '0' and the input if it isn't.

You can't impress us by showing how something would be shorter
with alternate syntax. You have to argue that this syntax doesn't
disrupt other things, and that it's useful enough by itself. I'm
not saying I never needed both the index and the value of an array
at the same time, only that it wasn't that common.

If you give us an example of code you wrote or saw someplace
that needed both, perhaps we could think of how to write it in
a more perlish idiom.

> Gabor Szabo  wrote:
> 
>>Nothing would happen if
>>    keys %myhash;
>>would always return the keys sorted numerically.
> 
> Gaal Yahas  wrote:
> 
>>What if I want to sort lexically? Or by some other criteria? 
>>You want to always take the hit?
> 
> 
> sort() is using a default sorter if you don't provide it your own
> sorter. It does take the hit when you're indifferent. If keys would
> sort numerically / lexically ascending by default, it could be
> modified to use the sort() syntax:
>    keys {$b cmp $a} %myhash;

Yes, but the point is that there isn't *any* sorting going on
with the keys keyword today. You always need to explicitly call
sort (with or without a user-defined comparator) if you want
the keys sorted.

Gaal

-- 
Gaal Yahas <gaal at forum2.org>
http://gaal.livejournal.com/



More information about the Perl mailing list