Ok, I'll respond to a couple of points, below, but I think a lot of
folks are confusing some operational concepts here, and it's getting
hard to un-peel them.

A container has many attributes, even if Perl won't let us control them.
Those include:

        1. Storage
        2. Conversion of the whole container to another type
        3. Type assigned to keys (array: int, hash: scalar)
        3.5 Type used to compare/order keys (array: int, hash: string)
        4. Type assigned to values
        5. Value which keys default to
        6. Value which values default to
        7. Behavior on normal instantiation (@a=(1,2,3))
        8. Behavior on sparse instantiation (@a[2]=3)
        9. Behavior on lazy instantiation (@a=(1..Inf))
        10. How other types are converted on input
        11. Syntax for indexing
        12. Syntax for listifying
        13. Syntax for holistic container access
        14. Methods available

3 and 4 vs 5 and 6 are an interesting thing to get your brain around.

When you talk about an array having a default value, I don't think of
that as controlling 1..5, 7 or 10..14. I do see it having an effect on 6
and possibly an effect on 8 and 9 depending on implementation.

That is to say that C<@a[10] = $mumble> shouldn't care about the default
value for that array. I'm not defaulting it. If the default TYPE for
that array doesn't handle the value that I'm trying to store, then type
conversion comes into play, and as someone pointed out and undef might
become 0 for arrays of ints. But if the default value for my array of
ints is 100, then why on earth would assigning it undef result in 100
and not 0?!

I could see defining an atomic type which has an alternate conversion
for an undefined value. So, for example, you might have an alternate
type of int that converts undef to 100. Then, of course, assigning undef
to an element of an array of such values should give you 100, AND
assigning undef to an element of an array of such values that defaults
to 200 should still yield 100!

Now again, we have to ask how much of this Perl is going to let us do. I
have no idea, and don't want to suggest one way or the other. But, to
mash them together into one operation restricts future expansion far too
much.

On Wed, 2003-01-29 at 10:32, Mark J. Reed wrote:

> 1. Ordering.  The elements of an array have a defined order.  The elements
>    of a hash do not.

I mentioned storage. Unless your container semantics demand a sort
before searching or listing, the underlying storage impacts ordering.

Elements of a has ARE ordered, just not the way you may expect.

> 2. Contents.  Arrays are a collection of values.  Hashes are a collection
>    of key/value associations.  The indices in an array are just a by-product
>    of the above fact that the values are ordered; there is no intrinsic
>    association between, say, the number 1 and the second element.

Arrays are a collection of key/value pairs, where the key is stored by
virtue of positioning in order to save space and increase access time.
Don't start thinking that that information is lost! Of course there's an
association between 1 and the second element. What you meant to say is
that there's no storage allocated to the number 1, because we can infer
the key's value based on position.


>         4. delete.   No reason you can't remove an element from an array, 
>                      but it's effectively a splice - the later elements move
>                      down.

I disagree. This would un-exists an item, and leave it in a state that
would require auto-vivification if it were accessed in future.

>         5. exists.   exists(a[i]) ::== 0 <= i < a.length

This is a mistake, since you're going to end up claiming that something
exists when it literally does not.

> Now let's look at array operators on hashes.
> 
>         1. push.    As long as the argument is a Pair, I guess this
>                     makes sense.  h.push( k => v ) ::= h{k} = v

Well, the argument would be a list of Pairs, actually.

>         2. pop.     Problem: no ordering.  There is no "last" value.
>                     which one should this remove?

There is no problem. It will pop the Pair that would be last if you
converted to a list. That might be massively expensive to determine, but
as long as the documentation warns the same way it does for converting
to a list, then you're not causing any new problems.

You keep asserting that there's  no ordering to Hashes, but that's not
true. I don't blame you, even the Perl docs get it wrong sometimes.

>From the P5 docs:

        perldata: "Hashes are unordered collections of scalar values
        indexed by their associated string key."
        
        perlfunc/keys: "order is subject to change in future versions of
        perl, but it is guaranteed to be the same order as either the
        "values" or "each" function produces"
        
So, they're not "unordered". They just have an ordering that you can't
rely on if you change their contents. So, I would expect that:

        (@a=%b)[0].key eq (shift %b).key

wouldn't you? That is assuming that C<@a=%b> assigns into C<@a> a list
of pairs, not the expanded form that Perl5 assigns, but my point holds
either way, just not the example.

>         3. shift.   ditto.

No problem here. In fact, it's almost always a cheap operation too.
Sometimes (e.g. for some types of external data) it will be expensive,
but see above.

>         4. unshift. identical to push.
> 
> My point boils down to this: the semantics are fundamentally different no
> matter how similar or different the syntax is.

Only if you want them to be.

-- 
Aaron Sherman <[EMAIL PROTECTED]>
This message (c) 2003 by Aaron Sherman,
and granted to the Public Domain in 2023.
Fight the DMCA and copyright extension!


Reply via email to