If I can assume:
@x = 3..5;
say pop @x; # prints 5
@x = 3..5;
push @x, 6;
say pop @x; # prints 6
say pop @x; # prints 5
What should I expect for the following?
@x = 3..Inf;
say pop @x; # heat death?
@x = 3..Inf;
push @x, 6; # heat death or
# an array with infinity + 1 elements?
say pop @x; # prints 6?
say pop @x; # heat death?
Dan
The way I understand the magicness of lazy lists, I'd expect:
@x = 3..Inf;
say pop @x; # prints Inf
@x = 3..Inf;
push @x, 6; # an array with the first part being
# lazy, and then the element 6
say pop @x; # prints 6
say pop @x; # prints Inf
say pop @x; # prints Inf
say pop @x; # prints Inf
# etc
The way I think of a lazy infinite list is kind of like a special object. It needs to keep track of what the start is and what the end is. Every other element doesn't actually exist, but is calculated based on the index of the FETCH/STORE/SPLICE/whatever call.
Also, any list that contains and infinite list becomes tied. The container list's FETCH would change so that any accessed index that falls within the indexes "owned" by the infinite list would be dispatched to the infinite list. So, with a list like:
@array = ('a','b','c',2..Inf,"woops");
Elements 0, 1, and 2 would be accessable as normal, but then elements 3 through Inf would be dispatched to the infinite list. However, since "woops"'s index is also Inf, and that index is "owned" by the infinite list, it would be impossible to access it except through a pop call (which doesn't look at indexes at all).
Actually, I think that this logic could apply to any array/list constructed with .. or ..., and an infinite list would just be a special case of that. It would definitely be useful in cases like: @array = 1..2000000000;
- Joe
I guess that's true with X..Y lazy lists. I thought there were other
ways to make lazy lists, like giving it a closure that gets called
lazily to populate the list with the result's being cached. I can't
remember the syntax though. I think gather was one way. Maybe I'm just
remembering wrong.
Anyhow, I was thiking that was how X..Inf was implemented. That would
be foolish in this case.
how 'bout
@x = gather{
loop{
take time
}
} # can this be @x = gather { take time loop }
push @x, "later";
say pop @x; # "later"
say pop @x; # heat death?
say @x[rand]; # how about now?
> Also, any list that contains and infinite list becomes tied. The container list's FETCH would change so that any accessed index that falls within the indexes "owned" by the infinite list would be dispatched to the infinite list. So, with a list like:
>
> @array = ('a','b','c',2..Inf,"woops");
>
> Elements 0, 1, and 2 would be accessable as normal, but then elements 3 through Inf would be dispatched to the infinite list. However, since "woops"'s index is also Inf, and that index is "owned" by the infinite list, it would be impossible to access it except through a pop call (which doesn't look at indexes at all).
I was wondering about lazy list where we don't know how many element it
might generate. Admittedly, I picked a poor example. I would right to
assume woops would also be accessable with @array[-1], right?
Dan
I'm a bit confused by your syntax, but I think I
understand what you mean. I was under the impression
that loops were not lazily evaluated, but essentially
run until they were broken out of. The advantage of
using an infinite list is just that you have an
iterator that never runs out.
Oh yeah, that would work too. :)
- Joe
Can probably be made to work right.
: say pop @x; # heat death?
Yes.
: say @x[rand]; # how about now?
Well, that's always going to ask for @x[0], which isn't a problem.
However, if you say rand(@x), it has to calculate the number of
elements in @x, which could take a little while...
: I was wondering about lazy list where we don't know how many element it
: might generate. Admittedly, I picked a poor example. I would right to
: assume woops would also be accessable with @array[-1], right?
Yes, that should probably be made to work as well.
Larry
----- Original Message -----
From: Larry Wall <la...@wall.org>
Date: Wednesday, July 7, 2004 11:25 pm
Subject: Re: push with lazy lists
> On Fri, Jul 02, 2004 at 09:32:07PM -0500, Dan
Hursh wrote:
> : how 'bout
> :
> : @x = gather{
> : loop{
> : take time
> : }
> : } # can this be @x = gather { take time loop }
> : push @x, "later";
> : say pop @x; # "later"
>
> Can probably be made to work right.
>
> : say pop @x; # heat death?
>
> Yes.
>
> : say @x[rand]; # how about now?
>
> Well, that's always going to ask for @x[0], which
isn't a problem.
> However, if you say rand(@x), it has to calculate
the number of
> elements in @x, which could take a little while...
Why would the second pop be a heat death, and why
would rand always return 0?
- Joe
To answer the latter first, rand (with no arguments) returns a number
greater than or equal to 0 and less than 1 which when used as an index
into an array gets turned into a 0.
As to why the second pop would take forever, I'd imagine that in order
to pop the last item from the array, all of the elements must first be
generated (i.e. we lose all laziness). And unless we have some magic for
generating them from either end, it'll start at the begining and
continue until the end, then stop before it ever does the pop. :-)
-Scott
--
Jonathan Scott Duff
du...@pobox.com
Ah, right, I should known that, in both cases. (: Thanks for answering my silly questions.
- Joe
Case 1 (Inf) would give Inf (which can be argued, since infinite many more
elements are bigger than any given finite number), and case 2 could give an
exception ...
Regards,
Phil
Perl can't tell the difference between finite and infinite gather/take
lists. (It literally can't--this is practically a perfect example of
the halting problem.) So if you ask a gather/take for its length, the
best thing Perl can do is to start gathering elements, hoping to
eventually find an end.
Unfortunately, since "gather { take time }" is an infinite list, it's
quite impossible for the gathering to ever finish, short of the universe
coming to an end, the computer crashing, or a sysadmin killing the
program. (Unless safe mode restricts the length of lazy lists, which I
would recommend given the existence this little ball of hate.)
--
Brent "Dax" Royal-Gordon <br...@brentdax.com>
Perl and Parrot hacker
Oceania has always been at war with Eastasia.
I know it makes no difference in this particular case, but my personal
preference would be to define rand(@x) as
rand(@x) == @x.rand == @x[ rand int @x ] == @x[ rand(1) * @x ]
guaranteeing a uniform distribution unless adverbial modifiers are used.
Dave.
> rand(@x) == @x.rand == @x[ rand int @x ] == @x[ rand(1) * @x ]
>
> guaranteeing a uniform distribution unless adverbial modifiers are
> used.
Meaning I can do:
$avg_joe = rand @students :bell_curve;
?
=Austin
The hard part being to pick a random number in [0,Inf) uniformly. :-)
: Meaning I can do:
:
: $avg_joe = rand @students :bell_curve;
:
: ?
Certainly you can do that, but it'll only work if some version of
rand declares either a ?$bell_curve option or a +$bell_curve option.
(And the latter will work only if we can extend multiple dispatch to
pay attention to named parameters, which we've explicitly put into the
category of things the Parrot folks are allowed to ignore for 6.0.0.)
Larry
Half of all numbers in [0, Inf) are in the range [Inf/2, Inf). Which
collapses to the range [Inf, Inf). Returning Inf seems to satisfy the
uniform distribution requirement: if you have a number you're waiting
to see returned, just wait a bit longer...
> : Meaning I can do:
> :
> : $avg_joe = rand @students :bell_curve;
> :
> : ?
>
> Certainly you can do that, but it'll only work if some version of
> rand declares either a ?$bell_curve option or a +$bell_curve option.
> (And the latter will work only if we can extend multiple dispatch to
> pay attention to named parameters, which we've explicitly put into
> the category of things the Parrot folks are allowed to ignore for
> 6.0.0.)
Why is this a parrot-ism and not a P6-ism? The behavior of multiple
dispatch, itself supposedly a tunable thing, seems likely to be a
P6-internal rather than a Parrot thing. (In fact, I would think this is
a simple behavior: discover the "rand" token, realize that there's a
multi sub with that name, emit a MD call, keep going.)
=Austin
Yeah, but it doesn't satisfy the random requirement very well, unless
Inf == 42 some infinitesimal part of the time.
: > Certainly you can do that, but it'll only work if some version of
: > rand declares either a ?$bell_curve option or a +$bell_curve option.
:
: > (And the latter will work only if we can extend multiple dispatch to
: > pay attention to named parameters, which we've explicitly put into
: > the category of things the Parrot folks are allowed to ignore for
: > 6.0.0.)
:
: Why is this a parrot-ism and not a P6-ism? The behavior of multiple
: dispatch, itself supposedly a tunable thing, seems likely to be a
: P6-internal rather than a Parrot thing. (In fact, I would think this is
: a simple behavior: discover the "rand" token, realize that there's a
: multi sub with that name, emit a MD call, keep going.)
Parrot's MD only supports positional arguments for now. All named
arguments *could* in theory be mapped to positions if you know all
the declarations for a particular name, but things get hairy when
two different sub declarations put their positional parameters
(which *may* be called by name) in different orders. That's the
basic problem. It's one of those things that we know is possible to
solve inefficiently, but we're not sure we want to solve it efficiently
for 6.0.0. If you want to work it all out, though, many of us would
be overjoyed.
There may be some intermediate solutions for when we know the parameter
orderings are consistent, of course, and if one of those solutions
made it into 6.0.0, it wouldn't prevent a more general solution later.
I think that's the likeliest scenario. People will want to do MD on
named parameters, as the rand example illustrates. Depending on the
solution, that might force us to declare ?$bell_curve rather than
+$bell_curve for now, or transmogrify some +$bell_curve declarations
into ?$bell_curve declarations internally so that Parrot's MD engine
has a position for them.
Larry
I like the 1/n trick used in the Perl Cookbook (Picking a Random Line from
a File). We could apply the same idea here:
rand($_)<1 && ($chosen=$_) for 1...Inf;
All right, it would take a bit longer for your program to run, but that's
a performance issue for them to sort out on *-internals.
-David "sure Moore's Law will deal with it in a year or two" Green
I just have to say, I am forever indebted to that algorithm.
Luke
> All right, it would take a bit longer for your program to run, but that's
> a performance issue for them to sort out on *-internals.
Like, it would take a bit longer than your lifetime :-)?
> -David "sure Moore's Law will deal with it in a year or two" Green
'And my new '986 does the infinite loop in under 3.5 seconds' :-)
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.
But maybe we could get an index of Inf working like -1 (ie. the last value):
@x = 1 .. Inf;
push @x, "a";
print $x[Inf];
would print an "a" ...
although, on this line of reasoning,
print $x[rand(@x)];
would always print "a" ....
I believe that an array should get an .rand-Method, which could do the right
thing.
@x= (1 .. Inf, "b", -Inf .. -1, "c", 1 .. Inf);
print $x[rand(@x)],"\n" while (1);
could give
Inf
Inf
-Inf
b
c
Inf
-Inf
and so on - an "random" element of a random part of the array, and an infinite
list gives Inf (or -Inf) as a random element (as explained above in this
thread).
So an array would have to know of how many "pieces" it is constructed, and
then choose an element among the pieces ...
I'd think that's reasonable, isn't it?
Regards,
Phil
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. If we allow it, should we also allow people to take the
NaNth element of an array? How about the 'foobar'th element?
What happens if I take the Infiniteth element of a finite list?
I think I would prefer if using Inf as an array index resulted in a
trappable error.
--Dks
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.
> If we allow it, should we also allow people to take the
> NaNth element of an array?
NaN is already a "number" (internal representation), so it doesn't get
converted.
As there is no NaNth element, it would return either undef (as in (0,1,2)[8] )
or an exception, as it is no numeric index.
> How about the 'foobar'th element?
'foobar' is converted to a number, so the 0th element is taken.
> What happens if I take the Infiniteth element of a finite list?
undef, as in 8th element of (1,2,3).
> I think I would prefer if using Inf as an array index resulted in a
> trappable error.
That's a possibility. It could raise an exception as with NaN.
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.
$x[NaN] gets an exception
because NaN is already of numeric type (as in $x=tan(pi/2)), but can not be
associated to any index.
So I'd propose to solve this argument based on "can be used as an index".
An infinite array (and even an finite) can be asked for an infinite index -
which has an value for infinite arrays.
This is just so there's no special coding for some indizes necessary - imagine
a lookup like
@x = (10,9,9,8,8,8,6,3,2,1,1,1,1,0);
$number = scalar(<STDIN>)+0;
print $x[10/$number];
which would work for *any* input, and just give undef for most of them.
Regards,
Phil
BTW: is it possible to define a look-up table as in
@x = (1, 2, 3, 4, 5, Inf .. Inf)
to get everything from [5] on to be Inf?
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 < arod...@entermail.net >
> 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.
<OT>
As a side note, being what one would probably call a mathematically
oriented person, it is very natural for me, dealing with programming
languages to notice the mathematical aspects of them.
To be more precise, and without delving into the details of the actual
nature of mathematical objects and related phylosophical ideas, for me
(and not only for me) mathematics is *also* a language, just as natural
as many so-called "natural languages".
Also, mathematics, as a language indeed is one that aims at obtaining the
most possible expressiveness with the least possible verbose expense. In
this sense it should be very interesting from the perspective of Perl...
This is why *for example* I was so interested in the discussion about
"outer products" (but then I wouldn't call them so!)
Hope not to have contributed negatively to the noise/signal ratio on
list...
</OT>
Michele
--
>> try sleeping on it, that usually works.
> I think you're right. Usually it works every time. ;-)
I don't know about that.
I tried sleeping on a big big problem and we're now divorsed.
- "Tralfaz" on sci.math, "Re: About a big big problem" (edited)
Yeah. If I didn't write that, I certainly meant it.
--Andrew
> Half of all numbers in [0, Inf) are in the range [Inf/2, Inf). Which
> collapses to the range [Inf, Inf).
It's not that simple. By that reasoning, 10% of all numbers in
[0,Inf) would be in [Inf/10,Inf), also reducing to the range
[Inf,Inf). For that matter, 99% of them would be in [Inf/100,Inf),
which would reduce to [Inf,Inf). But you can't do that kind of
arithmetic with Inf. You're trying to pretend you're working with a
natural number or a specific real, when in fact it's a cardinality (or
a class of cardinalities, or an infinite set of cardinalities, or
something along those lines). If you want to do addition and
multiplication on Inf, you have to redefine addition and
multiplication to get away from the CPU's finite arithmetic, and you'd
also need to treat Inf more completely than Perl does. (Perl treats
all infinities as the same, which is (mathematically speaking)
patently rediculous, because for practical purposes it never matters
to most software, and if somebody wants to clone Mathematica they'll
be writing their own math library anyway.)
It would be *nice* to have this stuff properly supported in a
programming language, sure, but it would also be a ton of work and can
probably wait for at least Perl7.
Oh, and the hardware available to most folks isn't up to the challenge
of picking a properly random number between 0 and Inf yet, either.
Most of the time it wouldn't fit in RAM. Predicting when this
challenge will be overcome is left as an exercise to the reader.
--
$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}}
split//,"ten.thgirb\@badanoj$/ --";$\=$ ;-> ();print$/
> Does it even make sense to take the Infiniteth element of an array?
No. At best, it would be undefined, so we could define it to return
undef.
> I think I would prefer if using Inf as an array index resulted in a
> trappable error.
Or that, yeah.
> 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.
[...]
> 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.
If that were the case, 0/Inf would == 0.
Also, if that were the case, 0..Inf would be a finite list. (It is
trivial to prove that 0..N is a finite list with finite cardinality
for all natural numbers N. So if you set N equal to Inf, 0..Inf would
have finite cardinality, if Inf is a natural number.)
This is obviously some new definition of Inf of which I was not
previously aware.
You should have used a hash in the first place.
--
BASH is great, it dumps core and has clear documentation. -Ari Suntioinen
> Also, if that were the case, 0..Inf would be a finite list. (It is
> trivial to prove that 0..N is a finite list with finite cardinality
> for all natural numbers N. So if you set N equal to Inf, 0..Inf would
> have finite cardinality, if Inf is a natural number.)
>
> This is obviously some new definition of Inf of which I was not
> previously aware.
Well, after reading my sentence one more, I see what may have caused some
troubles.
Inf is not in N; but *in my understanding* it fits naturally as an extension
to N, that is, Inf is (or can be) integer as is "after" N...
This won't be written in math books, I know.
> Also, if that were the case, 0..Inf would be a finite list. (It is
> trivial to prove that 0..N is a finite list with finite cardinality
> for all natural numbers N. So if you set N equal to Inf, 0..Inf would
> have finite cardinality, if Inf is a natural number.)
If I extend the natural numbers N with Inf to a new set NI (N with Inf), then
0 .. n (for n in NI) need not be finite ...
Sorry for my (very possibly wrong) opinion ...
Regards,
Phil
>> This is obviously some new definition of Inf of which I was not
>> previously aware.
> Well, after reading my sentence one more, I see what may have caused
> some troubles. Inf is not in N; but *in my understanding* it fits
> naturally as an extension to N, that is, Inf is (or can be) integer
> as is "after" N...
>
> This won't be written in math books, I know.
Actually, it's discussed to death in math books, but math books deal
with Inf in ways Perl isn't prepared to do. If you want to treat
infinities as numbers, then you have to be prepared to have different
infinities.
>> Also, if that were the case, 0..Inf would be a finite list. (It is
>> trivial to prove that 0..N is a finite list with finite cardinality
>> for all natural numbers N. So if you set N equal to Inf, 0..Inf would
>> have finite cardinality, if Inf is a natural number.)
>
> If I extend the natural numbers N with Inf to a new set NI (N with
> Inf)
The problem is, NI is not a group with respect to addition for any
definition of addition of which I am aware. Translated from mathese
to English, that means NI isn't terribly useful or meaningful or
interesting. J and R and C (i.e., the integers and the reals and the
complex numbers) are much more worthy of consideration, because they
form groups with respect to addition.
It is possible to construct a group that includes infinities, but NI
isn't it, and for Perl purposes it doesn't seem necessary.
Though if someone wants to hack surreals into 6.1, that'd be cool. :-)
Larry
> > If I extend the natural numbers N with Inf to a new set NI (N with
> > Inf)
>
> The problem is, NI is not a group with respect to addition for any
> definition of addition of which I am aware. Translated from mathese
In other words, or more briefly, and in many different contexts, it is
well known that "Inf" can't be fully arithmetized...
Michele
--
> As you see, we have to conclude that either Cantor's "proofs" are
> worthless wastes of ink,
Or we can conclude that your posts are worthless waste of web space.
- "Theorist" in sci.math, "Re: Cantor Paradox :-)" (slightly edited)
As a lurking mathematician on the list, I thought that it might be
insightful to offer some comments at this point. Apologies in advance
if I'm repeating something that happened at the beginning of the thread.
Once you start talking about non-finite sets of numbers, percentages
start to become amusingly meaningless. Classic examples: the set of
integers and the set of positive integers have the same size; there are
as many points on the perimeter of a square as there are in its
interior.
For many of the same underlying reasons, it's quite impossible to have a
flat random probability distribution across the integers (or reals, for
that matter).
Hardware people are lazy, and have given us only a finite number of bits
to work with. So, that gives us an excuse to be lazy as well in the
non-Bignum case: if the list is known in advance to be infinite, then we
just take C<rand(@x)> to be a flat distribution over the range of the
double, or whatever Perl is using for such things. It's not like people
will be able to access any other elements in the array ;-). If the
array size is unknown, and the programmer doesn't want to risk
accidental heat death, I see no problem with C<rand(@x,$lower,$upper)>
for those cases; i.e., if the size of the array appears to be larger
than abs($lower) and abs($upper), then we fall back to using those
limits.
People using C<rand(Inf)> with Bignums deserve to be spanked. :) A
graceful solution in that case would be to interpret that as C<tan(rand
(pi/2))*exp(pi*tan(rand(pi)))>, or better yet, C<tan(rand(pi))*exp
(pi*tan(rand(pi)))>, since that roughly reflects what humans will do
when you ask them for a random real number (mouth off some random digits
and multiply by a "random" power of 10). Besides, there's always C<abs>
if people can't stomach C<rand(Inf)> returning negative numbers. If
they're using Bignums, they also ought to be savvy enough to figure out
some other distribution if desired.*
Peter
*If people think C<rand(Inf)> should only return positive things, I'm
fine with that. It's just annoying to have to type C< * (int(rand
(2))*2-1)>.