On Wednesday 14 July 2004 04:55 am, Ph. Marek wrote:
> On Wednesday 14 July 2004 08:39, David Storrs wrote:
> > > To repeat Dave and myself - if
> > >   @x = 1 .. Inf;
> > > then
> > >   rand(@x)
> > > should be Inf, and so
> > >   print $x[rand(@x)];
> > > should give Inf, as the infinite element of @x is Inf.
>
> Please take my words as my understanding, ie. with no connection to
> mathmatics or number theory or whatever. I'll just say what I believe is
> practical.
>
> > Does it even make sense to take the Infiniteth element of an
> > array?...after all, array indices are integers, and Inf is not an
> > integer.
>
> I'd believe that infinity can be integer, ie. has no numbers after the
> comma; and infinity is in the natural numbers (?), which are a subset of
> integers.
Infinity is outside of the numbers. When we speak of infinity we mean not some 
particular "number" which is greater than all the other ones, but rather some 
variable which has escaped the bounds of the finite and the numbers.
> [etc.]
> To summarize:
>       @x= ('a', 5 .. Inf, 'b');
>       $x[0] is 'a'
>       $x['foo'] is 'a'
>       $x[-1] is 'b'
>       $x[2] is 6
>       $x[2002] is 2006
> I believe these are clear and understandable.
>
>       $x[Inf] is 'b'
>       $x[-2] is Inf
>       $x[-10] is Inf
>       $x[-2] is Inf
> These would result in simply interpolating the indizes.

Personally I think it's a fairly bad idea to be able to index an array on Inf; 
we have $x[-1] and such already to get the "right" side of an array, and I 
think it makes more sense, especially in light of the fact that you can 
reasonably ask for $x[-2], but not $x[Inf-1]. And, you might want to think of 
it in terms of behavior. Not because I say cop out and go with whatever has 
the easiest implementation, but because if the mechanism for array 
subscripting is anything but simple, nobody will ever know if they've got it 
right.

I think I agree that the conceptually neatest way to look at "fancy" lazyish 
arrays is by using iterators. An iterator should be able to support at least 
one of: getting elements in sequence from "left" to "right", getting elements 
in sequence from the right to the left, and indexing straight into the middle 
of things. "push" and "pop" work the obvious way based on this, and I suggest 
that indexing should behave as though it's merely counting elements from 
"left" or "right" by taking elements from the iterator, even if it skips 
doing it for real for purposes of speed or other implementation fun.

So if we have @x = [1, 3, 5, 6 .. 9, 10 .. Inf, 42];
Then conceptually it's three (or maybe a little more) array-iterators on the 
inside, and one smart meta-iterator that knows how to take elements from its 
child iterators in order, and knows how to do the math to support indexing 
when possible. As for the component iterators: [1, 3, 5] is like any regular 
array, we know it can get its first, its last, or any one by index. And it 
knows its length. Good. [6 .. 9], might be driven by a function that returns 
{ $^index + 6 }. It knows how long it is, it can index in all three ways, and 
it knows where it starts, which means we can convert an index on the outer 
array into an index on this chunk. [10 .. Inf] is similar; again we can 
generate it by a simple function, and come in from the right; but its 
"length" is Inf, and if we ask it to iterate starting at the right, it should 
return an endless stream of Inf. Similarly a lookup on any negative index 
inside it should return Inf. 42 is just one number, so questions of indexing 
it are moot, but its "distance" from the left is Inf. So, there's no way to 
access the 42 by any positive index of @x, and no way to ever get it by 
successive "shift". Overall I suggest

(all code is sequential)
$a = shift @x;  # $a = 1; @x = [3, 5, 6 .. 9, 10 .. Inf, 42]
shift @x; shift @x; # @x = [6 .. 9, 10 .. Inf, 42]
$a = $x[0];             # 6
$a = $x[1];              #7
$a = $x[5];             # 10
$a = $x[-1];            #42
$a = $x[Inf];   # No thanks
$a = $x[-2];            # Inf
$a = pop @x;    # $a = 42; @x = [ 6 .. 9, 10 .. Inf ]
repeat { $a = pop @x; } until $a != Inf; # Heat death

--Andrew Rodland < [EMAIL PROTECTED] >

Reply via email to