Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-18 Thread Allison Randal

On Fri, May 17, 2002 at 05:40:30PM -0600, Luke Palmer wrote:

> Back to from where this arose, however, I think LAST (and BETWEEN, if
> it will exist) should probably be PRE blocks. This is the only way it
> could be consistently possible to implement. It wouldn't make any
> sense to have it a PRE block on a while and a NEXT block on a foreach.

C can't be a C block, for the same reason "else" couldn't be
a NAMED block. A C fires just after execution enters the current
iteration's block. You're expecting C to fire in the block just
after the final iteration, but there is no block after the final
iteration. 

On C, I think we're all agreed that it should fire after the
final statement in one iteration and before the first statement in the
next iteration (if we get it at all). If you boil down the discussion to
it's barest essentials, the only thing at question is what values the
variables in the C block should have when it fires. The values
of the previous iteration or the following iteration?

The debate about look-aheads for arrays and array-like objects is a red
herring (though it's been interesting). It isn't necessary for either
option.

Allison



RE: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-17 Thread Luke Palmer

On 16 May 2002, Aaron Sherman wrote:

> On Thu, 2002-05-16 at 16:13, David Whipp wrote:
> > Aaron Sherman [mailto:[EMAIL PROTECTED]] wrote:
> > > You might not be able to REASONABLY get a length, so you return
> > > undef. In your documentation, you advise users not to take the length,
> > > but just dive right in and fetch the element you want, e.g.:
> > >
> > > my $pi2k = @pi_digits[2000];
> > 
> > In this case, I'd expect @pi_digits.length == Inf, not undef.
> 
> If I'm wrong about no proof existing for pi's infiniteness, I apologize.
Pi has been proven irrational, and anything that can be represented with a 
finite number of decimal places is rational. So, you're wrong.

> Pick your favorite series of discrete units n, where n may or may not be
> infinite, but where series[x] can be determined (though possibly at
> great cost) for all Perl-available positive integers, x.
> 
> That aside, the point holds. Tied arrays which point to complex systems
> may not have a known length (even in Perl5). We know this.

In which case, I think undef is fine. It's up to the programmer to decide 
whether (s)he wants to use arrays that will return undef or not. 

Back to from where this arose, however, I think LAST (and BETWEEN, if it 
will exist) should probably be PRE blocks. This is the only way it could 
be consistently possible to implement. It wouldn't make any sense to have 
it a PRE block on a while and a NEXT block on a foreach.

Luke




Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-16 Thread Erik Steven Harrison

 
--



On Thu, 16 May 2002 12:36:42  
 Miko O'Sullivan wrote:
>SUMMARY
>
>Arrays should always have known lengths because that's what arrays do.  This
>requirement is enforced culturally, not programmatically.

I totally agree that this should be enforced culturally. I think that the way a tied 
array (or hash, for that matter) should handle this in this way:

sub LENGTH { #Possible implicit sub for determining length
return undef but true; #or would this be is?
}

As Larry (I think) approximately said module and class authors should not use undef 
for false - it should mean undef. This seems pretty clear to me. "We have a length 
here, yes, but we don't know what it is yet. It's undefined".

-Erik


Is your boss reading your email? Probably
Keep your messages private by using Lycos Mail.
Sign up today at http://mail.lycos.com



RE: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-16 Thread Aaron Sherman

On Thu, 2002-05-16 at 16:13, David Whipp wrote:
> Aaron Sherman [mailto:[EMAIL PROTECTED]] wrote:
> > You might not be able to REASONABLY get a length, so you return
> > undef. In your documentation, you advise users not to take the length,
> > but just dive right in and fetch the element you want, e.g.:
> >
> > my $pi2k = @pi_digits[2000];
> 
> In this case, I'd expect @pi_digits.length == Inf, not undef.

If I'm wrong about no proof existing for pi's infiniteness, I apologize.
Pick your favorite series of discrete units n, where n may or may not be
infinite, but where series[x] can be determined (though possibly at
great cost) for all Perl-available positive integers, x.

That aside, the point holds. Tied arrays which point to complex systems
may not have a known length (even in Perl5). We know this.





Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-16 Thread Ashley Winters

On Thursday 16 May 2002 01:13 pm, David Whipp wrote:
> Aaron Sherman [mailto:[EMAIL PROTECTED]] wrote:
> > You might not be able to REASONABLY get a length, so you return
> > undef. In your documentation, you advise users not to take the length,
> > but just dive right in and fetch the element you want, e.g.:
> >
> > my $pi2k = @pi_digits[2000];
>
> In this case, I'd expect @pi_digits.length == Inf, not undef.

I'd agree with that. Perhaps you want *@lazy.length to work?

Ashley Winters



RE: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-16 Thread David Whipp

Aaron Sherman [mailto:[EMAIL PROTECTED]] wrote:
> You might not be able to REASONABLY get a length, so you return
> undef. In your documentation, you advise users not to take the length,
> but just dive right in and fetch the element you want, e.g.:
>
> my $pi2k = @pi_digits[2000];

In this case, I'd expect @pi_digits.length == Inf, not undef.


Dave.



Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-16 Thread Aaron Sherman

On Thu, 2002-05-16 at 12:36, Miko O'Sullivan wrote:

> I submit for consideration the idea that if an array doesn't always have a
> defined length then it ceases to be that incredibly handy construct that we
> currently call "array".  If arrays can answer "I dunno" when asked how long
> they are, that's taking away a useful feature, not adding one. If we dumb
> down arrays we're going to have to spend a lot of time smarting up our code.
> Suddenly every time you want to use an array in scalar or numeric context
> you first have to check if it has a defined length. That doesn't appeal to
> my sense of laziness, and it triggers my sense of impatience.

I don't see that that's the case. I do see that in some cases, you will
get a "useless array" in the sense that your "dumb" code:

my @ary is Too::Smart::Array = (1,2,3); # uh... is that how tie will work?
if @ary.length { ... do stuff ... }

So, this code will work correctly as long as @ary has a valid numeric
value, but if it doesn't your code will treat that has having zero
elements. That seems roughly correct to me. The only "correcter" thing
would be something like:

my @ary is Too::Smart::Array = (1,2,3);
if my $len = @ary.length {
...do stuff...
} else unless defined $len {
die "$0: Yes, we have no bananas: $!";
}

Why would you want to do this? Let's say that you're tying an array to a
very large, possibly infinite set of data, or a source of data that is
slow. You might not be able to REASONABLY get a length, so you return
undef. In your documentation, you advise users not to take the length,
but just dive right in and fetch the element you want, e.g.:

my $pi2k = @pi_digits[2000];

Users who do not understand this will get odd results, true, but they
get odd results that result in a reasonable default, IMHO.





Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-16 Thread Miko O'Sullivan

SUMMARY

Arrays should always have known lengths because that's what arrays do.  This
requirement is enforced culturally, not programmatically.

DETAILS

I submit for consideration the idea that if an array doesn't always have a
defined length then it ceases to be that incredibly handy construct that we
currently call "array".  If arrays can answer "I dunno" when asked how long
they are, that's taking away a useful feature, not adding one. If we dumb
down arrays we're going to have to spend a lot of time smarting up our code.
Suddenly every time you want to use an array in scalar or numeric context
you first have to check if it has a defined length. That doesn't appeal to
my sense of laziness, and it triggers my sense of impatience.

OTOH, it doesn't seem Perlish to force the programmer to do something he or
she may really not want to do.  As always, Larry is wise in saying "an array
implementation can return anything it jolly well pleases".

So my proposal is that building array classes is like tying arrays and
hashes is right now: there are certain expectations and people won't like
your code if you don't follow the norms.  You should always return a defined
length.  Documentation for arrays should indicate that they should always
return a defined length. If you don't then you've broken the social contract
and people will frown at you.  If applicable to Perl6: the base class for
tied arrays that most people will use to create their own arrays should set
the length method as abstract so it needs to be overridden.

-Miko




Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-16 Thread Aaron Sherman

On Wed, 2002-05-15 at 13:02, Larry Wall wrote:
> Aaron Sherman writes:
> : Should a tied and/or lazy array be forced to present a length on demand,
> : or can length return undef on indeterminate arrays?
> 
> An array implementation can return anything it jolly well pleases, but
> I'd say undef would be a reasonable thing to return if the length is
> indeterminate.  Then you can at least get warnings if you try to use
> the undefined value later.  The class could even tag the undef with a
> property containing an unthrown exception that explains why the length
> is indeterminate, since Perl 6 will support interesting values of
> undef.

I had to give this one a day... First off, I'm sick so I wasn't really
thinking clearly enough to respond yesterday. But more importantly, I
learned more from this one post about how you see things working in
Perl6 than from most of the Apocalypses.

So, you see something like:

method length() {
if (...we think we know...) {
return .len; # See discussion on inlining accessors
} else {
return undef but exception("Homer::Doh: no known length");
}
}
[...]
$foolen = @foo.length // die("$0: Why, oh why: $!");

Interesting. Even more so because applications that don't take the time
to check @foo.length's return value for definedness will go on assuming
it has no elements, which is probably a good fall-back for code that
isn't paying enough attention (and of course, there's the warning).





Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-15 Thread Larry Wall

Aaron Sherman writes:
: Should a tied and/or lazy array be forced to present a length on demand,
: or can length return undef on indeterminate arrays?

An array implementation can return anything it jolly well pleases, but
I'd say undef would be a reasonable thing to return if the length is
indeterminate.  Then you can at least get warnings if you try to use
the undefined value later.  The class could even tag the undef with a
property containing an unthrown exception that explains why the length
is indeterminate, since Perl 6 will support interesting values of
undef.

Larry



Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-15 Thread Aaron Sherman

On Sun, 2002-05-12 at 15:43, Miko O'Sullivan wrote:
> From: "David Whipp" <[EMAIL PROTECTED]>
> > It it too much to ask, of the creator of a tied array, to implement
> > their code in such a way that *reading* an element of that array
> > does not have significant side-effects?
> 
> Actually, I think that *is* a significant imposition. The whole point of
> tied arrays ( and hashes, scalars, etc) is that they act like arrays but
> internally do whatever they want.
> 
> But could we go back a step?  Could somebody explain why we need
> lookaheads, or perhaps what exactly a "lookahead" is in this context?  Part
> of the current interface for tied arrays is that they know how long they
> are.  It seems like it would be a relatively simply algorithm to say "if
> there are still elements left in the array then populate the loop variable
> with the next element and run the block.  Else, leave the variables as they
> are, run the LAST block."

This brings up a concern that I've had with the idea of lazy arrays in
Perl for a while. An awful lot of things in the current Perl codebase
rely on the idea that an array (even a tied one) has a length at any
given time (even if it changes).

To change that assumption may have some serious impact on a lot of
features of the language.

You cannot, for example, reasonably do:

(0..Inf).length

You might special-case that particular one (return Inf if either
end-point of a lazy array is Inf), but this is a simple example. Tie
creates much more interestingly clever examples

Should a tied and/or lazy array be forced to present a length on demand,
or can length return undef on indeterminate arrays?





Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-12 Thread Trey Harris

In a message dated Sun, 12 May 2002, Miko O'Sullivan writes:

> From: "David Whipp" <[EMAIL PROTECTED]>
> > It it too much to ask, of the creator of a tied array, to implement
> > their code in such a way that *reading* an element of that array
> > does not have significant side-effects?
>
> Actually, I think that *is* a significant imposition. The whole point of
> tied arrays ( and hashes, scalars, etc) is that they act like arrays but
> internally do whatever they want.

This reminds me of my first experience writing a kernel handler for the
/proc filesystem.  I was just learning how it worked, and made the handler
increment an internal variable and print it every time the file was read.
I was surprised to see the following behavior, when I cat'd the file
several times:

$ cat /proc/test
Counter is 0
$ cat /proc/test
Counter is 3
$ cat /proc/test
Counter is 9

$ cat /proc/test
Counter is 13
$ cat /proc/test
Counter is 16

(Note the extra newline after 9.)  This is absolutely correct behavior--if
you know how the standard C library implements file I/O, you can see
what's going on (hint: I used %d in the format to sprintf).  But it's
wildly unintuitive.

But this is just how things are.  If the act of reading a particular data
structure has side effects, especially side effects that cause the
semantics of the data structure to alter, code which expects ordinary
semantics, where reading is idempotent, will behave unexpectedly.

Trey




Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-12 Thread Miko O'Sullivan

From: "David Whipp" <[EMAIL PROTECTED]>
> It it too much to ask, of the creator of a tied array, to implement
> their code in such a way that *reading* an element of that array
> does not have significant side-effects?

Actually, I think that *is* a significant imposition. The whole point of
tied arrays ( and hashes, scalars, etc) is that they act like arrays but
internally do whatever they want.

But could we go back a step?  Could somebody explain why we need
lookaheads, or perhaps what exactly a "lookahead" is in this context?  Part
of the current interface for tied arrays is that they know how long they
are.  It seems like it would be a relatively simply algorithm to say "if
there are still elements left in the array then populate the loop variable
with the next element and run the block.  Else, leave the variables as they
are, run the LAST block."

-Miko




RE: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-09 Thread Aaron Sherman

On Thu, 2002-05-09 at 13:22, David Whipp wrote:
> Aaron Sherman [mailto:[EMAIL PROTECTED]] wrote:
>  > what about 
> > > 
> > > while (do_something_with_side_effects_and_check_still_ok()) {
> > > 
> > > I presume we don't want to do look-ahead here.
> > 
> > Yes, I think he was saying exactly that we will do look-ahead 
> > here. "we don't guarantee order of evaluation" is exactly saying
> > that, no?
> 
> As the "he" refered to, let me be absolutely clear that I am
> *not* suggesting any type of look-ahead here. I was specifically
> talking about the C loop, where Perl is expected to
> implement the iterator. In a C loop, the programmer
> controls the iterator, and would be surprised by a loop-ahead.

My bad. Missed the transition from foreach to while... oops!





RE: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-09 Thread David Whipp

Miko O'Sullivan wrote:
> Just checking here: is PRE_LAST a separate and non-mutually exclusive
> concept from LAST?  I.e., would this make sense:
> 
>foreach @arr -> $i {
>   PRE_LAST {print "before last loop\n"}
>   LAST {print "after last loop\n"}
>   print "$i\n";
>}
> 
> If so, wouldn't look-aheads still result in chaos and 
> confusion for tied arrays?

Under the hypothetical PRE_LAST block, I'd expect your code to
make sense.

It it too much to ask, of the creator of a tied array, to implement
their code in such a way that *reading* an element of that array
does not have significant side-effects?

If one is doing object oriented programming, then the concept
of substitutability requires that I can use a subclass anywhere
that I can use the base class. When I use an array, I expect
to be able to read elements from it, at random, without
breaking it. If a tied array does not permit me to read
its elements without worrying about hideous side effects,
then it is not an array.


> If not, then I'd definitely disagree: to me, for's and 
> while's are just different flavors of "loop" and should
> behave the same in every way possible.

The great things about things that are different, is that
they are permitted to differ. C and C are
not synonyms. They have distinct characters.

To me, the concept of PRE_LAST makes sense in the context of
C, and is easy to implement. In the case of a C,
or C loop, the concept may still make sense: but the
details of the semantics need careful consideration. There's
a great danger of analysis-paralysis if we cogitate on the
difficult case. So perhaps we can first seek agreement on
the easy case.


Dave.



Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-09 Thread Miko O'Sullivan

> The implication is that we can only provide advanced "PRE_LAST"
> style blocks (or their equiv.) on the C loop. The fact
> that they are impossible on the C loop should not
> constrain our thinking for the C loop.

Just checking here: is PRE_LAST a separate and non-mutually exclusive
concept from LAST?  I.e., would this make sense:

   foreach @arr -> $i {
  PRE_LAST {print "before last loop\n"}
  LAST {print "after last loop\n"}
  print "$i\n";
   }

If so, wouldn't look-aheads still result in chaos and confusion for tied
arrays?

If not, then I'd definitely disagree: to me, for's and while's are just
different flavors of "loop" and should behave the same in every way
possible.

-Miko




RE: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-09 Thread David Whipp

Aaron Sherman [mailto:[EMAIL PROTECTED]] wrote:
 > what about 
> > 
> > while (do_something_with_side_effects_and_check_still_ok()) {
> > 
> > I presume we don't want to do look-ahead here.
> 
> Yes, I think he was saying exactly that we will do look-ahead 
> here. "we don't guarantee order of evaluation" is exactly saying
> that, no?

As the "he" refered to, let me be absolutely clear that I am
*not* suggesting any type of look-ahead here. I was specifically
talking about the C loop, where Perl is expected to
implement the iterator. In a C loop, the programmer
controls the iterator, and would be surprised by a loop-ahead.

The implication is that we can only provide advanced "PRE_LAST"
style blocks (or their equiv.) on the C loop. The fact
that they are impossible on the C loop should not
constrain our thinking for the C loop.


Dave.



Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-07 Thread Graham Barr

On Tue, May 07, 2002 at 12:27:08PM -0500, Allison Randal wrote:
> On Tue, May 07, 2002 at 03:15:48PM +0100, Graham Barr wrote:
> > 
> >  LAST   Executes on implicit loop exit or call to last()
> > Loop variables may be unknown
> 
> Not exactly "unknown". It's just that, in a few cases, their values may
> have changed by the time the LAST block is executed.

OK, unspecified.

> 
> > And I think this thread is proposing
> > 
> >  FIRST   A PRE block that is executed only on the first itteration
> >  of the loop
> > 
> >  BETWEEN A PRE block that does not execute for the first iteration
> >  of the loop.
> > 
> > So FIRST and BETWEEN are just shorthand for
> > 
> >  my $count;
> >  loop {
> >PRE {
> >  if ($count++) {
> ># BETWEEN code here
> >  }
> >  else {
> ># FIRST code here
> >  }
> >}
> >  }
> 
> Almost. What people are pushing for is more like:
> 
>  BETWEEN A NEXT block that does not execute for the last iteration
>of the loop.

IMO, it cannot. That is because you cannot always know if you are at
the end of a loop until you have executed the condition. Therefore BETWEEN
would have to be a PRE block.

> This may seem like a trivial difference at first glance, but it's a
> matter of scope. The latter interpretation means that code such as:
> 
>   for 1..3 -> $thing {
>   print $thing _ ", ";
> 
>   BETWEEN {
>   print $thing _ "\n";
>   }
>   }
> 
> Will output:
> 1, 1
> 2, 2
> 3,
> 
> Not:
> 1, 2
> 2, 3
> 3,

But consider when this is a while loop, how do you stop BETWEEN being
called before the last iteration.

> Which seems intuitively right. 

Not to me :-)

Graham.




Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)

2002-05-07 Thread Allison Randal

On Tue, May 07, 2002 at 03:15:48PM +0100, Graham Barr wrote:
> 
>  LAST   Executes on implicit loop exit or call to last()
>   Loop variables may be unknown

Not exactly "unknown". It's just that, in a few cases, their values may
have changed by the time the LAST block is executed.

> And I think this thread is proposing
> 
>  FIRST A PRE block that is executed only on the first itteration
>of the loop
> 
>  BETWEEN A PRE block that does not execute for the first iteration
>of the loop.
> 
> So FIRST and BETWEEN are just shorthand for
> 
>  my $count;
>  loop {
>PRE {
>  if ($count++) {
># BETWEEN code here
>  }
>  else {
># FIRST code here
>  }
>}
>  }

Almost. What people are pushing for is more like:

 BETWEEN A NEXT block that does not execute for the last iteration
 of the loop.

 my $count;
 loop {
   PRE {
 unless ($count++) {
   # FIRST code here
 }
   }
   NEXT {
 if () {
   # BETWEEN code here
 }
 }

This may seem like a trivial difference at first glance, but it's a
matter of scope. The latter interpretation means that code such as:

for 1..3 -> $thing {
print $thing _ ", ";

BETWEEN {
print $thing _ "\n";
}
}

Will output:
1, 1
2, 2
3,

Not:
1, 2
2, 3
3,

Which seems intuitively right. 

It's only with variables lexically scoped outside the loop and that
change values in the condition itself that we encounter Damian's
conundrum.

Allison