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