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.

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

On CBETWEEN, 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 CBETWEEN 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 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 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 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-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-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-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-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-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 Cforeach loop, where Perl is expected to
implement the iterator. In a Cwhile 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 Cforeach loop. The fact
that they are impossible on the Cwhile loop should not
constrain our thinking for the Cforeach loop.


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 Cforeach loop. The fact
 that they are impossible on the Cwhile loop should not
 constrain our thinking for the Cforeach 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

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. Cwhile and Cforeach are
not synonyms. They have distinct characters.

To me, the concept of PRE_LAST makes sense in the context of
Cforeach, and is easy to implement. In the case of a Cwhile,
or Cloop 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 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 Cforeach loop, where Perl is expected to
 implement the iterator. In a Cwhile 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-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 (the loop will execute again) {
   # 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



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.