Re: Spare brackets :-)

2003-01-29 Thread Smylers
Michael G Schwern wrote:

> On Tue, Jan 28, 2003 at 12:11:18PM +1300, [EMAIL PROTECTED] wrote:
> 
> > Has anyone considered removing with the syntactic distinction
> > between numeric and string indexing -- that is, between array and
> > hash lookup?
> 
> PHP works this way.

Well, for some definition of "work", anyway.

> http://www.php.net/manual/en/language.types.array.php
> 
> So that makes a nice case study to investigate.

The manual is strangely quiet on how this duality fits together, but
through using PHP I've managed to work some of it out.

Basically in PHP there are just hashes, but hashes retain the order in
which elements are stored.  When iterating with C or C you
get elements back in the order you put them in:

  $colour = array('grass' => 'green', 'sky' => 'blue',
'orange' => 'orange');
  print_r($colour);
  
  # output:
  Array
  (
  [grass] => green
  [sky] => blue
  [orange] => orange
  )

If you add an element that doesn't have a key, then PHP finds the
maximum key that looks like a non-negative integer, adds one to it, and
uses that as the key for the new element, or uses zero if no elements
have such keys.

This means that if you never assign any explicit keys you can make it
seem like the hash is a 'normal' array:

  $colour = array('purple', 'black', 'silver');
  print_r($colour);

  Array
  (
[0] => purple
[1] => black
[2] => silver
  )

But it isn't.  Remember that elements retain the order in which they
were stored.  So if you set them not in numerical order then they remain
in that order:

  $colour = array();
  $colour[1] = 'taupe';
  $colour[3] = 'red';
  $colour[0] = 'zephyr';
  $colour[2] = 'pink';
  print_r($colour);

  Array
  (
  [1] => taupe
  [3] => red
  [0] => zephyr
  [2] => pink
  )

And if you remove an element from the middle of an array, the existing
elements keep their previous indices, so the indices are no longer
consecutive:

  $colour = array('purple', 'black', 'silver', 'gold');
  unset($colour[2]);
  print_r($colour);

  Array
  (
  [0] => purple
  [1] => black
  [3] => gold
  )

And if you put that element back, well it doesn't go there but appears
at the end:

  $colour = array('purple', 'black', 'silver', 'gold');
  unset($colour[2]);
  $colour[2] = 'bronze';
  print_r($colour);

  Array
  (
  [0] => purple
  [1] => black
  [3] => gold
  [2] => bronze
  )

The ordering means that it's possible to shift elements off the
beginning of a hash, which is fine:

  $colour = array('grass' => 'green', 'sky' => 'blue',
'orange' => 'orange');
  array_shift($colour);
  print_r($colour);

  Array
  (
  [sky] => blue
  [orange] => orange
  )

There's also something in there which checks for non-negative integer
keys, and if so renumbers them after shifting.  This helps keep up the
pretence that the hash can be used as an array:

  $colour = array('purple', 'black', 'silver', 'gold');
  array_shift($colour);
  print_r($colour);

  Array
  (
  [0] => black
  [1] => silver
  [2] => gold
  )

But this can have surprising consequences if you are trying to associate
numbers with particular elements:

  $days = array(1 => 'day', 7 => 'week', 14 => 'fortnight',
  365 => 'year');
  array_shift($days);
  print_r($days);

  Array
  (
  [0] => week
  [1] => fortnight
  [2] => year
  )

Zero days in a week?  And the same thing happens even if the keys are
quoted, so that they are strings that happen to look like integers but
not actual integers:

  $days = array('1' => 'day', '7' => 'week', '14' => 'fortnight',
  '365' => 'year');

Trying that on a hash where some of the keys happen to look like
integers and some don't results in the former being renumbered and the
latter being left alone.

Is that enough?

The amazing thing is that most of the time, despite the above, what PHP
calls arrays do actually work well enough.  But really PHP has hashes
with elements that retain their storage order plus some awkward hacks
that may make them seem more like arrays in certain circumstances.  It's
messy.  It's bordering on evil.

And I've never found it to have any advantage over the Perl way of
allowing the programmer to specify which data structure is required
rather than making the interpreter guess.

I cannot think of a worse example for Perl to follow.

Smylers



Re: Spare brackets :-)

2003-01-29 Thread Aaron Sherman
On Wed, 2003-01-29 at 05:29, Leopold Toetsch wrote:
> John Williams wrote:
> 
> > I think you are still overlooking the autovivification behavior.
> > i.e. What is the difference between these:
> > 
> >1)   $a{1234567} = 1;
> > 
> >2)   $a[1234567] = 1;
> > 
> > Answer: #1 creates 1 element.  #2 creates 1,234,567 elements!

> Not currently: 2) does
> - generate a sparse hole between old size and up to ~index
> - generate one data chunk near index
> - store the PerlInt at index

I covered this under the term "storage". The storage is different for
arrays and hashes. This we know.

But, why do I need to waste a set of balanced tokens to indicate that
difference? Historical compatibility with Perl5? Perhaps. That's not a
bad reason actually, given how much this could wig people out (just look
at the response on this list :)

Also, you don't always pre-declare in Perl, and the following would be
ambiguous:

$x[7] = 8;

That could auto-vivify an array ref or a hash ref, and choosing one or
the other is kind of scary. I think you could work around that, but it
would require a real dedication to the IDEA that Perl has a generic
container type.

-- 
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!





Re: Spare brackets :-)

2003-01-29 Thread Austin Hastings

--- Sam Vilain <[EMAIL PROTECTED]> wrote:

> =head2 includes( [ I, ] [ I ])

Where the  and/or  are obviously junctions.

 if ($container.includes(any("ant", "beaver", "cow", "duck"))(
...

This is *SO* cool.

=Austin



Re: Spare brackets :-)

2003-01-29 Thread Leopold Toetsch
John Williams wrote:


I think you are still overlooking the autovivification behavior.
i.e. What is the difference between these:

   1)   $a{1234567} = 1;

   2)   $a[1234567] = 1;

Answer: #1 creates 1 element.  #2 creates 1,234,567 elements!



Not currently: 2) does
- generate a sparse hole between old size and up to ~index
- generate one data chunk near index
- store the PerlInt at index

Reading non existent data in the hole generates then PerlUndef's on the fly.


~ John Williams


leo




Re: Spare brackets :-)

2003-01-29 Thread Sam Vilain
On Wed, 29 Jan 2003 18:04, Michael G Schwern wrote:
> On Tue, Jan 28, 2003 at 12:11:18PM +1300, [EMAIL PROTECTED] wrote:
> > This may sound like a silly idea but ...
> >
> > Has anyone considered removing with the syntactic distinction between
> > numeric and string indexing -- that is, between array and hash lookup?
>
> PHP works this way.
> http://www.php.net/manual/en/language.types.array.php
>
> So that makes a nice case study to investigate.

Stick this in yer pipe n smoke it.  I haven't actually written the module 
yet, just the man page.  But I think it might just be crazy enough to 
implement :-).

The restriction that a key is a scalar and a value is a blessed object 
could be removed, but it was a useful pre-condition for my use.

The DWIMy function that tells the difference between an int and a string is 
at the end.

=head1 NAME

Container::Object - set/array/hash/bag/whatever of objects

=head1 SYNOPSIS

  use Container::Object;
  $coll = Container::Object->new();

  push @$coll, foo => (bless { }, "bar");
  print ref $coll{foo}; # prints "bar"
  print ref $coll[0];   # prints "bar"
  print ref( ($coll->members)[0] ); # prints "bar"

=head1 DESCRIPTION

This modules implements a generic container of objects, that is, an
unordered, ordered, or keyed collection of objects, with or without
duplication of items.

This means that depending on how you treat your container, it
automagically behaves like a Set, Bag, Array, Hash or some perverse
combination of a subset of the above.

=head2 EH?

In the beginning, there was the array.  Then Larry empowered the Hash
with Perl.  Some other geezer followed up with C, hashes
that also retain ordering.  Jean-Louis Leroy wrote C,
which was a bit like an array but without the ordering, and no
duplicate elements.  And Java as well as PHP have a poorly considered
bastard half and half mix of the two.

This container class tries to implement as many of the above classes
as possible, with DWIM and no more than O(log n) execution time being
the overriding principle.

=head2 Keys vs Values

Keys to objects in Container::Objects MUST be unblessed,
non-overloaded, scalar values.  You can supply a tied scalar wherever
a key is accepted, but the value is read once.

Values MUST be blessed objects.  They can be scalars, hashes,
references, whatever.  It doesn't really matter.

=head2 Indexes vs Keys

A very DWIMy function is used to tell the difference between a string
that is intended for use as a hash key, and a whole number that is
intended for use as an index lookup.

This is required to get correct behaviour from looking up the element
at index 0, versus the item with hash key "0".

=head2 Duplicate Items

It is possible to have two objects with the same hash key, or even
indeed an object may appear twice in the container with a single hash
key.

However, if objects are to be fetched by (hash) key, and duplicate
objects are found, the I object inserted with that key is
returned (that is, the one with the highest numerical index).  This
emulates the behaviour of a hash.

To avoid unnecessary, stale or duplicate entries in the container
lying around, you can use the C method instead of C
to put your objects in.

=head2 Key Fabrication

If objects are inserted without hash keys, they are inserted with an
empty hash key (from a user's perspective; internally a hash is
computed from the object's address in memory for objects with
undefined keys so the container is still well balanced).

If objects are inserted with hash keys, they are added to the logical
end of the container.

=head2 Algorithms and execution time

Simple N-bucket hashing with complete re-indexing is used for
simplicity of the code and speed for the general target case.

Each bucket contains a series of hash table entries, which is an array
of pointers to C structures and Cs.  Each entry also contains
a reference to the next entry in the numerical index, and copy of its
hash key to fill the bucket entry to four CPU words.

The bucket index is a flat array of pointers, plus a flat array of
C<(index # => pointer)> pairs to various points in the index array
chain; so that inserts can be performed in near constant time (the
index is merely updated).

=head1 CLASS METHODS

=head2 new( [ [ I =E ] I] ... )

Return a new C containing the elements passed in
I.  The elements must be objects.  Keys are optional.

=head1 INSTANCE METHODS

=head2 insert( [ [ I =E ] I] ... )

Add objects to the C.

Adding the same object several times is not an error, but any
C will contain at most one occurance of the same
hash key/object pair, and the numeric index always remains continuous,
no holes, starting at zero.  Returns the number of elements that were
actually added.

When adding elements to the collection's numerical index, inserts into
the list at the decided (or given) position.

=head2 replace( [ [ I =E ] I] ... )

Replaces objects in the C.

Virtually identical to C, but likes to replace element

Re: Spare brackets :-)

2003-01-29 Thread martin
>> In particular, it would seem that
>>   %foo[$key]
>> would be just as easy for the compiler to grok as
>>   %foo{$key}

On Mon, 27 Jan 2003 15:39:19 -0800, Damian Conway <[EMAIL PROTECTED]> wrote:
> Sure. But then is this:
>
> $ref[$key]
>
> an array or hash look-up???

Yes, well I suppose that could be considered one of the things I hadn't figured
out yet.

But is seems to me that if we're changing "$X[$n]" to "@X[$n]", then it would
be more consistent to change "$ref->[$key]" to "@$ref[$key]".  Except of course
that mixing prefix and postfix notation is horrible, so perhaps "$ref@[$key]" and
"$ref%[$key]". (I'd assumed that "%[" and "@[" would be single symbols?)

> Decided at runtime?

That might be OK, except (as others have pointed out) for auto-vivification,
where the object doesn't exist before we operate on it.

Maybe we would get away with the shorthand "$ref[$index]" *except* where
autovivification is desired, and then we'd have to use the long-hand
"$ref@[$index]" and "$ref%[$index]" versions?

Hm, actually, I think I could class that as a feature, if the reader --
human or compiler -- could know just by looking whether auto-viv is expected.

-Martin





Re: Spare brackets :-)

2003-01-29 Thread Michael G Schwern
On Tue, Jan 28, 2003 at 12:11:18PM +1300, [EMAIL PROTECTED] wrote:
> This may sound like a silly idea but ...
> 
> Has anyone considered removing with the syntactic distinction between
> numeric and string indexing -- that is, between array and hash lookup?

PHP works this way.
http://www.php.net/manual/en/language.types.array.php

So that makes a nice case study to investigate.


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl Quality Assurance  <[EMAIL PROTECTED]> Kwalitee Is Job One



Re: Spare brackets :-)

2003-01-29 Thread John Williams
On 28 Jan 2003, Aaron Sherman wrote:

> I'm not sure I recall the sufficient, yet irrelevant technical reasons.
> I certainly can't think of anything. It also helps in the case of
> objects that are non truly arrayish or hashish:
>
>   my SuperTree $foo;
>   $foo["Munge"]; # Returns the node whose value is "Munge"
>   $foo[0]; # Returns a node based on tree-position
>
> The only remaining behavior of braces that I can think of as different
> from brackets is auto-quoting, and is there a good reason that brackets
> could not auto-quote?

I think you are still overlooking the autovivification behavior.
i.e. What is the difference between these:

   1)   $a{1234567} = 1;

   2)   $a[1234567] = 1;

Answer: #1 creates 1 element.  #2 creates 1,234,567 elements!
I think that is a big enough difference that perl should not be asked
to guess.

Similar precendents are + vs ~, == vs eq, etc.

~ John Williams




Re: Spare brackets :-)

2003-01-28 Thread Adam Turoff
On Tue, Jan 28, 2003 at 09:24:50AM -0800, Austin Hastings wrote:
> --- Dan Sugalski <[EMAIL PROTECTED]> wrote:
> > At 8:47 AM + 1/28/03, Piers Cawley wrote:
> > >>  $ref[$key]
> > >>
> > >>  an array or hash look-up???
> > >
> > >Decided at runtime?
> > 
> > How? People use strings as array indices and ints/floats as hash 
> > indices, and count on autoconversion to Make It Work.
> 
> On the one hand: Java/ECMA/J-script does it.

That's nice, but Perl isn't Java/ECMAScript/JavaScript/JScript/C/C++/Pascal.
It's Perl.  Perl uses square brackets for arrays, and curly braces for
hashes.  Period.  And Perl 6 will continue in the path of Perl 1..5,
*not* in the path of some other broken syntax.

If you have any questions about this, please refer to the 1st, 2nd, or
3rd editions of Programming Perl, or to any of the millions of Perl
programmers who have that distinction hard-wired into their wetware.

Z.




Re: Spare brackets :-)

2003-01-28 Thread Dan Sugalski
At 5:07 PM -0500 1/28/03, Aaron Sherman wrote:

On Tue, 2003-01-28 at 16:34, Dan Sugalski wrote:

 At 4:17 PM -0500 1/28/03, Aaron Sherman wrote:
 >  Now the question becomes, do you WANT them
 >for readability?

 Given that Larry's answer has been a resounding "yes" all along,


I'm not sure that this specific case was brought up.


I am. Larry was clear--square brackets for array access, squiggle 
brackets for hash access.
--
Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk


Re: Spare brackets :-)

2003-01-28 Thread Aaron Sherman
On Tue, 2003-01-28 at 16:34, Dan Sugalski wrote:
> At 4:17 PM -0500 1/28/03, Aaron Sherman wrote:
> >  Now the question becomes, do you WANT them
> >for readability?
> 
> Given that Larry's answer has been a resounding "yes" all along, 

I'm not sure that this specific case was brought up. I remember Larry
weighing in on the thread about using [] as the only list constructor,
but that's a different issue. Granted, I've been away focusing on work,
so I may have missed it.

> the 
> technical reasons (Which are, themselves, sufficient) are pretty 
> irrelevant.

I'm not sure I recall the sufficient, yet irrelevant technical reasons.
I certainly can't think of anything. It also helps in the case of
objects that are non truly arrayish or hashish:

my SuperTree $foo;
$foo["Munge"]; # Returns the node whose value is "Munge"
$foo[0]; # Returns a node based on tree-position

The only remaining behavior of braces that I can think of as different
from brackets is auto-quoting, and is there a good reason that brackets
could not auto-quote?

-- 
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!





Re: Spare brackets :-)

2003-01-28 Thread Dan Sugalski
At 4:17 PM -0500 1/28/03, Aaron Sherman wrote:

 Now the question becomes, do you WANT them
for readability?


Given that Larry's answer has been a resounding "yes" all along, the 
technical reasons (Which are, themselves, sufficient) are pretty 
irrelevant.
--
Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk


Re: Spare brackets :-)

2003-01-28 Thread Aaron Sherman
On Tue, 2003-01-28 at 11:49, Dan Sugalski wrote:
> At 8:47 AM + 1/28/03, Piers Cawley wrote:
> >Damian Conway <[EMAIL PROTECTED]> writes:
> >  > Sure. But then is this:
> >>
> >>$ref[$key]
> >>
> >>  an array or hash look-up???
> >
> >Decided at runtime?
> 
> How? People use strings as array indices and ints/floats as hash 
> indices, and count on autoconversion to Make It Work.

And it would. I'm not on one-side or another here, but I do see the
proposal working just fine.

$ref.fetch($key)

works even when $key is a string and $ref is an ARRAY ref.

$ref[$key]

is shorthand for

$ref.[$key]

which is in turn shorthand for

$ref.fetch($key)

and/or

$ref.store($key)

depending on how it's used.

Allowing $ref to be a hash reference doesn't change anything because
HASH's fetch and store methods (no matter how builtin or pre-optimized
they may be) will do the conversion.

You still need C<{}> vs. C<[]> for anonymous types, but I don't think
you NEED them for indexing. Now the question becomes, do you WANT them
for readability?

-- 
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!





Re: Spare brackets :-)

2003-01-28 Thread Piers Cawley
Dan Sugalski <[EMAIL PROTECTED]> writes:

> At 8:47 AM + 1/28/03, Piers Cawley wrote:
>>Damian Conway <[EMAIL PROTECTED]> writes:
>>  > Sure. But then is this:
>>>
>>> $ref[$key]
>>>
>>>  an array or hash look-up???
>>
>>Decided at runtime?
>
> How? People use strings as array indices and ints/floats as hash
> indices, and count on autoconversion to Make It Work.

Nope. The count on the fact that, at runtime you'll know whether $ref
is a hash or an array. But I'm not actually arguing for this, just
pointing out that it's not necessarily impossible (just way harder to
optimize). 

-- 
Piers



Re: Spare brackets :-)

2003-01-28 Thread Austin Hastings

--- Dan Sugalski <[EMAIL PROTECTED]> wrote:
> At 8:47 AM + 1/28/03, Piers Cawley wrote:
> >Damian Conway <[EMAIL PROTECTED]> writes:
> >  > Sure. But then is this:
> >>
> >>$ref[$key]
> >>
> >>  an array or hash look-up???
> >
> >Decided at runtime?
> 
> How? People use strings as array indices and ints/floats as hash 
> indices, and count on autoconversion to Make It Work.

On the one hand: Java/ECMA/J-script does it.

All objects are associative arrays. All arrays can be associative, on
demand. C Presto. Associative array.

On the other hand: This gets dangerous really quickly, since Perl's
autoconversion works differently. Specifically, since we treat things
as "strings unless they need to be otherwise" rather than treating them
as "the type that they were when you created them". (Javascript doesn't
have much in the way of I/O, so the act of getting data in is a bit of
an effort, and that effort usually has the side effect of providing
type data.)

Writing a roulette game may get challenging:

@colors["0"]   = Green;
@colors["00"]  = Green;
@colors["000"] = Green;

Do those get autoconverted to numbers? (They can, obviously. But they
shouldn't.)

This kind of thing points back at a discussion we had once before about
"more kinds of context" -- meaning at the time "numeric" versus
"string" versus ... whatever.

I think that if we do this we'd better know more about what we're
expecting versus what we're losing.

On the "losing" side, the difference between lowercase-array and
lowercase-hash is probably significant, performance-wise. Merging the
array and hash notions may cost a lot of speed for a lot of people.

On the "gaining/expecting" side is ... what? Freeing up curly braces?
Improving the syntax? Other stuff not obvious to me right now?

If we go that route, we could certainly include a new "pure array"
type:

my @trough = slop();
my PureArray @pa = ducks();
my PureHash @ph = dictionary();

=Austin




Re: Spare brackets :-)

2003-01-28 Thread Dan Sugalski
At 8:47 AM + 1/28/03, Piers Cawley wrote:

Damian Conway <[EMAIL PROTECTED]> writes:
 > Sure. But then is this:


	$ref[$key]

 an array or hash look-up???


Decided at runtime?


How? People use strings as array indices and ints/floats as hash 
indices, and count on autoconversion to Make It Work.
--
Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk


Re: Spare brackets :-)

2003-01-28 Thread Damian Conway
Sure. But then is this:

	$ref[$key]

an array or hash look-up???

 
Decided at runtime?

Doesn't help if $ref refers to a type that has both hash-like and array-like
accessability. And that will be very common, since all Perl 6 regexes return
such objects.

Damian




Re: Spare brackets :-(

2003-01-28 Thread John Williams
ECMAscript already tried this.

Bad idea.

If your hash keys happen to look like large numbers (e.g. you
have 7-digit product codes) as soon as you store one of them, it says:
"Oh, this looks like a number, so we'll store it like an array" and
happily creates a million empty array entries for you.

~ John Williams


On Tue, 28 Jan 2003 [EMAIL PROTECTED] wrote:

>
> This may sound like a silly idea but ...
>
> Has anyone considered removing with the syntactic distinction between
> numeric and string indexing -- that is, between array and hash lookup?
>
> In particular, it would seem that
>
>   %foo[$key]
>
> would be just as easy for the compiler to grok as
>
>   %foo{$key}
>
> but would mean that we could stop worrying about the precedence of
> postfix/infix "{", and things like
>
>   if %test { $count++ }
>
> would not require whitespace before the "{" to be disambiguated.
>
> I don't have a complete solution as anonymous array and hash construction would
> still need different syntaces, but has anyone else thought about this?
>
> - Martin
>
>




Re: Spare brackets :-)

2003-01-28 Thread Piers Cawley
Damian Conway <[EMAIL PROTECTED]> writes:

>> This may sound like a silly idea
>
> It's been suggested previously.
>
>
>> Has anyone considered removing with the syntactic distinction between
>> numeric and string indexing -- that is, between array and hash lookup?
>
> Yes. We rejected the idea.
>
>
>> In particular, it would seem that
>>   %foo[$key]
>> would be just as easy for the compiler to grok as
>>   %foo{$key}
>
> Sure. But then is this:
>
>   $ref[$key]
>
> an array or hash look-up???

Decided at runtime?

-- 
Piers



Re: Spare brackets :-)

2003-01-27 Thread Damian Conway
This may sound like a silly idea


It's been suggested previously.



Has anyone considered removing with the syntactic distinction between
numeric and string indexing -- that is, between array and hash lookup?


Yes. We rejected the idea.



In particular, it would seem that

  %foo[$key]

would be just as easy for the compiler to grok as

  %foo{$key}


Sure. But then is this:

	$ref[$key]

an array or hash look-up???

Damian




Spare brackets :-)

2003-01-27 Thread martin

This may sound like a silly idea but ...

Has anyone considered removing with the syntactic distinction between
numeric and string indexing -- that is, between array and hash lookup?

In particular, it would seem that

  %foo[$key]

would be just as easy for the compiler to grok as

  %foo{$key}

but would mean that we could stop worrying about the precedence of
postfix/infix "{", and things like

  if %test { $count++ }

would not require whitespace before the "{" to be disambiguated.

I don't have a complete solution as anonymous array and hash construction would
still need different syntaces, but has anyone else thought about this?

- Martin