Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)
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)
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)
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)
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)
-- 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)
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)
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)
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)
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: Loop controls
From: Damian Conway [EMAIL PROTECTED] while (my $res = $search-getnext) { ...} has a valid meaning in Perl 6. In fact, it's meaning in Perl 6 is far more reasonable than in Perl 5. I don't think the new meaning makes sense at all. Essentially it's saying the statement gets run many times but the variable only gets declared once. It makes sense to declare a variable many times when it gets a fresh, new block for each declaration, like when it's inside a loop, but to use it in a statement that is run many times but declares the var only once seems like it ought to throw a warning about declaring the same variable in the same scope multiple times. use warnings 'P52P6'; that would point out potential problems like this. Cool idea. -Miko
Re: Loop controls
Miko O'Sullivan [EMAIL PROTECTED] writes: From: Damian Conway [EMAIL PROTECTED] while (my $res = $search-getnext) { ...} has a valid meaning in Perl 6. In fact, it's meaning in Perl 6 is far more reasonable than in Perl 5. I don't think the new meaning makes sense at all. Essentially it's saying the statement gets run many times but the variable only gets declared once. It makes sense to declare a variable many times when it gets a fresh, new block for each declaration, like when it's inside a loop, but to use it in a statement that is run many times but declares the var only once seems like it ought to throw a warning about declaring the same variable in the same scope multiple times. Yeah, but declaration happens at compile time, not runtime so there's no problem. Minor syntax quibble, it should in fact be: while (my $res = $search.getnext) { ... } Or, for shiny collection modification fun: while (my $res := $search.getnext) { ... } -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
RE: FIRST, BETWEEN, etc.. (was Re: Loop controls)
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)
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)
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)
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: Loop controls
while getNextValue() - $i { ... } while getOtherNextValue() - $i { ... } which generates no warning because each C$i is a parameter of the corresponding loop block, and hence scoped to that block. Ok, now I understand the plan. In brief, in the following example $result is scoped to the block that encloses the whole loop: while (my $res = $search-getnext) { ...} However, in the next example, $res is scoped to the loop: while $search-getnext() - $res { ...} Right? OK, that sounds cool. We still have loop-scoped variables. I'd like to suggest, though, that the first example would refuse to compile. If the plan is to significantly change the behavior of something as popular as that construct (and I did some research, it's VERY popular, details available on request), it would make more sense to refuse to compile than to DWIDM (Do What I Don't Mean). -Miko
Re: Loop controls
Ok, now I understand the plan. In brief, in the following example $result is scoped to the block that encloses the whole loop: while (my $res = $search-getnext) { ...} Yes. Because it's a lexical variable declared outside the closure controlled by the Cwhile. However, in the next example, $res is scoped to the loop: while $search-getnext() - $res { ...} Yes. Because it's a parameter of the closure controlled by the Cwhile. Right? OK, that sounds cool. We still have loop-scoped variables. I'd like to suggest, though, that the first example would refuse to compile. I don't think so. If the plan is to significantly change the behavior of something as popular as that construct (and I did some research, it's VERY popular, details available on request), it would make more sense to refuse to compile than to DWIDM (Do What I Don't Mean). H. By the same argument we should refuse to compile the very popular C$var[$idx] and C$var{key} constructs, since they no longer mean what they meant in Perl 5. I don't think that's the right answer. A construct like: while (my $res = $search-getnext) { ...} has a valid meaning in Perl 6. In fact, it's meaning in Perl 6 is far more reasonable than in Perl 5. However, Miko has highlighted a genuine transition problem, and one might imagine something like: use warnings 'P52P6'; that would point out potential problems like this. Damian
RE: Loop controls
On Mon, 2002-05-06 at 14:21, David Whipp wrote: Miko O'Sullivan [mailto:[EMAIL PROTECTED]] wrote: Sorry, I thought I'd expressed agreement at some point. I like the else\s+(if|while|for|loop) construct very much, and I think the programmers of the world would like it too. I know a some people have issues with where's the if but it's no worse than where's the semicolon or where's the filehandle closed. Is this the same as saying that Celse can be followed by *any* statement? If not, then we would need user-defined control statements (a property on a sub?) that can be used in the else context. No. That would introduce a problem that Larry has said (back when I started learning perl 3.x) that he wanted to avoid from C: the mystery of bare-blocks. What I was proposing was that else could be followed by a block (as normal) or by a whole control structure, which could be a loop or conditional and might itself contain an else. There's no ambiguity because all blocks still require braces.
FIRST, BETWEEN, etc.. (was Re: Loop controls)
I have been following this thread, but I would just like to inject a summary of the various related UPPERCASE blocks PREExecutes on block entry. Loop variables are in a known state POST Executes on block exit. Loop variables are in a known state NEXT Executes on implicit block exit or call to next() Loop variables are in a known state LAST Executes on implicit loop exit or call to last() Loop variables may be unknown 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 } } } Graham.
Re: FIRST, BETWEEN, etc.. (was Re: Loop controls)
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)
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: Loop controls
|On Mon, Apr 29, 2002 at 02:55:09PM -0500, Allison Randal wrote: | I still don't like the idea of Celsifs on loops. I already do an | instant double take with Celse of Where's the if? (with visions of | old Wendy's commercials dancing in my head). | |Me too. That's why the looping else should be spelled otherwise |IMHO. ]- count me too...
Re: Loop controls
| Damian, now having terrible visions of someone suggesting Celswhen ;-) | |Then may I also give you nightmares on: elsdo, elsdont, elsgrep, elstry ... ]- unlessdo, unlesdont, unlessgrep, unlesstry what about elsunless/unlesselse then :)
Re: Loop controls
perfect... in fact during the middle of the read someting similar come to my mind.. i.e the best way should be to have several in-loop-proprietes that we can test and decide what to do ... There have to be CAPITALISED words only for the block stuff ... raptor
RE: Loop controls
Miko O'Sullivan [mailto:[EMAIL PROTECTED]] wrote: Sorry, I thought I'd expressed agreement at some point. I like the else\s+(if|while|for|loop) construct very much, and I think the programmers of the world would like it too. I know a some people have issues with where's the if but it's no worse than where's the semicolon or where's the filehandle closed. Is this the same as saying that Celse can be followed by *any* statement? If not, then we would need user-defined control statements (a property on a sub?) that can be used in the else context. Also, if bare statements are allowed after an Celse, what about elsewhere? (no pun intended) Dave.
Re: Loop controls
Oh. Sorry. I suppose there was no discussion because there were no objections. I support it strongly. But everyone's already heard my opinion, and my opinion, and my opinion about it, so I'll be quiet now. Luke On 6 May 2002, Aaron Sherman wrote: It's odd, folks are still talking about the icky elsstuff, but I never saw any discussion of my BNF proposal. Was it that no one saw it, that my BNF was too rusty, or the idea of abandoning elsif for (in pseudo-ebnf) FLOW = ((if|unless|while|for) (E|CLOSURE_ARGS) | loop [E;E;E]) BLOCK [else (FLOW|BLOCK)] ; was discounted out of hand? I'd really like to hear why something so almost absurdly simple could be totally wrong. Heck, you could keep elsif around as a legacy if you wanted, but it becomes rather pointless. Doesn't this make the grammar shorter, and thus parsing more efficient as well? Someone had questioned the value of my example, so let me cite another: while $fh.getline - $_ { ... } else for users - $user { send_mail $user, Hello, $user, the file was empty; } else if openlog $$, 'pid', 'user' { syslog 'notice', The file was empty!; } else { die Cannot even invoke syslog... a bad day: $!; } This is a very clear chain of causality. I could re-write it with nested ifs and the like, but here we see the very heart of what I was trying to do, with very little waste.
Re: Loop controls
- Original Message - From: David Whipp [EMAIL PROTECTED] Is this the same as saying that Celse can be followed by *any* statement? If not, then we would need user-defined control statements (a property on a sub?) that can be used in the else context. Perhaps Celse is a binary operator? condition else expr. Like operator::or, but doesn't try to return a value. die unless foo; foo else die; Ashley Winters
Re: Loop controls
On Mon, May 06, 2002 at 10:53:11AM +1000, Damian Conway wrote: Allison asked: Hmmm... would CLAST not have the same problem as CBETWEEN? It also can't decide whether to execute until it knows whether the loop is going to iterate again. Yes, it does. Then I agree with Miko, it's not really a problem to explain the unusual cases of CBETWEEN, if we already have to explain the (identical) unusual cases of CLAST. Thinking about it this weekend, it seems that the concept might be made palatable if it were taught by first reviewing the current behaviour of closures and then explaining that CLAST and CBETWEEN behave the way they do because they are closures. Allison
Re: Loop controls
Miko O'Sullivan wrote: Acme::Don't - The opposite of `do' Wonderful job, Damian! I'll get to work on the complementary Acme::TryNotTo module. use Yoda; do {...} or not do {...}; not defined try {...}; ;-) Damian PS: that's valid Perl 6!
Re: Loop controls
Allison asked: Hmmm... would CLAST not have the same problem as CBETWEEN? It also can't decide whether to execute until it knows whether the loop is going to iterate again. Yes, it does. Damian
Re: Loop controls
Mike Lambert asked: It's also unnecessary. The Holy Scoping Rules actually work in your favour in this case. In Perl 6 you can just do this: while my $cond = blah() { ... } and C$cond is defined *outside* the block. Question then. Does the following code compile? while my $i = getNextValue() { } ... while my $i = getOtherNextValue() { } Yes, it compiles. But you get warnings about two lexical C$i's being declared in the same scope. Does it fail due to scoping $i twice within the same enclosing block, or is it sort of like a Scheme/OCaml interpreter where each definition creates a scoping for all the lines that follow it, and the second 'my $i' merely hides the $i scoped in the 'outer' scope. The latter. As Perl 5 does now. And yes, it's annoying. However, it won;t be an issue in Perl 6. The correct idiom in Perl 6 will almost certainly be: while getNextValue() - $i { ... } while getOtherNextValue() - $i { ... } which generates no warning because each C$i is a parameter of the corresponding loop block, and hence scoped to that block. Damian
RE: Loop controls
Damian Conway wrote: BUGS Unlikely, since it doesn't actually do anything. However, bug reports and other feedback are most welcome. Bug: don't { die } unless .error; doesn't DWIM (though the current behavour, do nothing, is logically correct). Dave.
Re: Loop controls
From: David Whipp [EMAIL PROTECTED] don't { die } unless .error; Whoa. This don't thing is starting to look eerily useful. Shades of the Parrot parody. -Miko
Re: Loop controls
On Fri, May 03, 2002 at 11:13:45AM -0700, David Whipp wrote: Damian Conway wrote: BUGS Unlikely, since it doesn't actually do anything. However, bug reports and other feedback are most welcome. Bug: don't { die } unless .error; doesn't DWIM (though the current behavour, do nothing, is logically correct). Yeah, this was on #perl yesterday. I still say it makes sense as-is. The conditionals aren't subtle, they simply ask to execute or not to execute?. In a: do { something } unless .error; you have two options: either the Cdo { something } executes, doing something, or the Cdo statement doesn't execute. With a Cdon't, you'd have the same two options. Either the Cdon't { whatever} executes, doing nothing, or the Cdon't doesn't execute, still doing nothing, just a little bit sooner. Allison
Re: Loop controls
It's also unnecessary. The Holy Scoping Rules actually work in your favour in this case. In Perl 6 you can just do this: while my $cond = blah() { ... } and C$cond is defined *outside* the block. Question then. Does the following code compile? while my $i = getNextValue() { } while my $i = getOtherNextValue() { } Does it fail due to scoping $i twice within the same enclosing block, or is it sort of like a Scheme/OCaml interpreter where each definition creates a scoping for all the lines that follow it, and the second 'my $i' merely hides the $i scoped in the 'outer' scope. This happens a lot in C where some compilers scope the initializer in a for loop to the enclosed loop (CodeWarrior), and some scope it in the enclosing block (GCC, MSVC). The latter approach causes people to write: for(int i=0; ... ) { ... } for(i=0; ... ) { ... } Which of course breaks when you remove the first loop. I always found that annoying...and that's what the following was used for, in those compilers: #define for if(0) {} else for Mike Lambert
Re: Loop controls
Allison Randal wrote: You know, I almost made a very similar reply. But I read through Damian's message a second time and changed my mind. CBETWEEN makes sense as a CNEXT minus CLAST. As a CPRE minus CFIRST it's less appealing. At the very least it begs a different name than BETWEEN (a name that implies it executes between each loop, not at the beginning of some). Hmmm... would CLAST not have the same problem as CBETWEEN? It also can't decide whether to execute until it knows whether the loop is going to iterate again. I've been watching this Loop controls thread with much interest. It is clear that there is some convenience in the concept of specialized blocks that execute FIRST or LAST or NEXT and BETWEEN has a large appeal, considering the large number of loops where something must be done every time except the first or every time except the last, except that I have never done the statistics to figure out whether every time except the last or every time except the first is more frequent, neither have I figured out whether BETWEEN is more frequently needed at the beginning or end of the loop body, and these latter two issues seem to be what everyone is going around and around about, without stating them. I think much of the discussion has resulted because there are many more conceptual meanings that could be useful, than there are suggested keywords to fulfil the meanings. I'll try to list the many conceptual meanings possible as I continue. As specialized blocks, the order is implicit, which means that separate specialized blocks would be needed for the four cases of BETWEEN which are: BETWEEN A) execute before the loop body every time except the first BETWEEN B) execute before the loop body every time except the last BETWEEN C) execute after the loop body every time except the first BETWEEN D) execute after the loop body every time except the last There has also been discussion about the best order of placement of the specialized loop blocks within the block, vs. the implicit execution order, and how that could be confusing sometimes. One thing I've noticed omitted from the discussion is that there are also cases such where the FIRST and BETWEEN might want to share code, or even the FIRST block might want to know if it is the last iteration. There has been the comment made that detection of the last iteration is hard (except, of course, for loop blocks with finite sequences) during the last iteration, that it is only after the last iteration that it is known that that iteration was, indeed, the last. It seems extremely trivial, however, to detect whether a particular iteration is the first. Now it could be said that LAST isn't needed, that you could just code that logic after the loop, but it seems to be true that LAST is only executed if the loop ever performs at least one iteration (and an explicit last statement is executed) or the iteration condition becomes false. This is a useful concept that (1) cannot be easily detected by user logic but can always be easily detected by the language loop control logic. The LAST block would certainly be a way to detect that, but the two cases differ: an explicit last statement could cause execution of the LAST block in the scope and with the variable values of the last iteration, but when the iteration condition becomes false, the scope and variable values are gone (unless heroically preserved, which probably could happen, but may have other nasty side effects that would be hard to understand). Also, the discussion of else conditions on loops seems very similar to LAST, so maybe we need five different LAST blocks: LAST A) executes when an explicit last statement occurs, in the scope of the last iteration LAST B) executes when the iteration condition becomes false, if at least one iteration has occurred LAST C) executes when the iteration condition becomes false, if there have been no iterations LAST D) legal only with loop loop: executes during the last iteration of a loop, before the loop body LAST E) legal only with loop loop: executes during the last iteration of a loop, after the loop body NEXT seems pretty simple: it executes after the loop body of an iteration, just before the iteration condition is reevaluated. Even FIRST could have two useful meanings: FIRST A) executes during the first iteration of a loop, before the loop body FIRST B) executes during the first iteration of a loop, after the loop body So it seems pretty clear that no amount of discussion will ever allow a few keywords to fulfil all of the possible variant implementations that might be possible and even useful, in various circumstances. I see several possible courses of action, there are perhaps more. 1) Choose the most useful meaning out of the above collections of possibilities, and disregard the others, forcing people who want to code them to do it the old way with discrete logic. 2) Invent new keywords for each possibility, proliferating keywords
Re: Loop controls
On Wednesday, May 1, 2002, at 02:27 PM, Aaron Sherman wrote: unless my $fh = $x.open { die Cannot open $x: $!; } else while $fh.getline - $_ { print; } else { die No lines to read in $x; } I think you need a better example--given that the unless clause throws an exception, the else while can just as easily be written as a while, no else. (Which I, personally, would find far clearer.) - Damien
Re: Loop controls
On Wed, 2002-05-01 at 18:47, Damien Neil wrote: On Wednesday, May 1, 2002, at 02:27 PM, Aaron Sherman wrote: unless my $fh = $x.open { die Cannot open $x: $!; } else while $fh.getline - $_ { print; } else { die No lines to read in $x; } I think you need a better example--given that the unless clause throws an exception, the else while can just as easily be written as a while, no else. (Which I, personally, would find far clearer.) No, I write this sort of thing all the time: if (foo) { die $! } else { stuff } It's clearer, IMHO, to the reader and maintainer of the code, exactly what is expected. It's taste and style and visual aesthetics, but we wouldn't have a postfix if if those things didn't matter in Perl.
Re: Loop controls
Luke Palmer wrote: Ooh! Why don't we have a dont command! With several variants: dont FILE dont BLOCK dont { print Boo } Would print: You really *should* be more careful what you wish for Luke. The following was just uploaded to the CPAN... Damian -cut--cut--cut--cut--cut--cut- NAME Acme::Don't - The opposite of `do' VERSION This document describes version 1.00 of Acme::Don't, released May 1, 2002. SYNOPSIS use Acme::Don't; don't { print This won't be printed\n };# NO-OP DESCRIPTION The Acme::Don't module provides a `don't' command, which is the opposite of Perl's built-in `do'. It is used exactly like the `do BLOCK' function except that, instead of executing the block it controls, it...well...doesn't. Regardless of the contents of the block, `don't' returns `undef'. You can even write: don't { # code here } while condition(); And, yes, in strict analogy to the semantics of Perl's magical `do...while', the `don't...while' block is *unconditionally* not done once before the test. ;-) Note that the code in the `don't' block must be syntactically valid Perl. This is an important feature: you get the accelerated performance of not actually executing the code, without sacrificing the security of compile-time syntax checking. LIMITATIONS Doesn't (yet) implement the opposite of `do STRING'. The current workaround is to use: don't {filename}; AUTHOR Damian Conway ([EMAIL PROTECTED]) BLAME Luke Palmer really should be *far* more careful what he idly wishes for. BUGS Unlikely, since it doesn't actually do anything. However, bug reports and other feedback are most welcome. COPYRIGHT Copyright (c) 2002, Damian Conway. All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the terms of the Perl Artistic License (see http://www.perl.com/perl/misc/Artistic.html)
Re: Loop controls
So, after all our discussions, my thinking regarding alternate blocks for loops is now running like this: 1. It would definitely be useful to be able to catch the failure of a block to iterate. 2. This ability should be available for all three types of block: Cwhile, Cfor, and Cloop. 3. The obvious syntax: while condition() { ... } else { ... } is fraught with difficulty because Celse is already so closely bound to Cif in the community consciousness. 4. Using Celse also encourages the expectation of Celsif, Celswhile, Celsunless, Celsinore, etc. But I don't believe the language can comfortably bear the weight of such expectations. Or such keywords. 5. My preferred option would be to restrict the alternative block to only being a simple block (i.e. no cascading), and to introduce it with some other keyword. 6. Cotherwise would seem to fit the bill rather nicely. So, I guess if Larry were to ask my opinion, I'd suggest that we allow: while condition() { ... } otherwise { ... } and: for list - $next { ... } otherwise { ... } and: loop ($i=0; i$max; i+=2) { ... } otherwise { ... } I now confidently await Larry's coming up with an entirely different solution ;-) Damian
Re: Loop controls
Miko O'Sullivan [EMAIL PROTECTED] writes: Damian, now having terrible visions of someone suggesting Celswhen ;-) Then may I also give you nightmares on: elsdo, elsdont, elsgrep, elstry ... To quote from the INTERCAL manual (and I doubt I'm the first to steal features from that powerful language): PLEASE ABSTAIN -- Ariel Scolnicov|http://3w.compugen.co.il/~ariels Compugen Ltd. |[EMAIL PROTECTED]Sometimes people write an 72 Pinhas Rosen St.|Tel: +972-3-7658117 accidental haiku. Damn! Tel-Aviv 69512, ISRAEL |Fax: +972-3-7658555 It just happened!
Re: Loop controls
I'm basically sold on Damian's conclusions. On the other hand the 'otherwise' clause still feels to me like a CAPITALS block. So, as a tweak, I suggest: while condition() { ... } NONE { ... } -- ralph
Re: Loop controls
ralph wrote: I'm basically sold on Damian's conclusions. On the other hand the 'otherwise' clause still feels to me like a CAPITALS block. So, as a tweak, I suggest: while condition() { ... } NONE { ... } Would you also change Celse to CELSE? I think lowercase is more appropriate because Cotherwise would be a control structure, rather than an event handler. Making it a CAPITAL block is also a little inconsistent: the other CAPITAL blocks attach behaviour to the *surrounding* block, not the *preceding* one. Damian
Re: Loop controls
Luke Palmer wrote: I'd rather have an in-betweener block too. Loops like this are very common, and I hate doing prefix commas, if you know what I mean. I realize NEXT often used for cleanup, so maybe you could introduse Yet Another block, BETWEEN (or SQUEEZE). Or are we just going to have to deal with this fact? We may just have to deal with the fact. Because there's a problem with in-betweener blocks. Consider: my $filename; while get_next_filename($filename) { FIRST { print list\n } my $fh = open $_ or die Can't open $filename; NEXT{ close $fh } print extract_id($fh); BETWEEN { print (-d $filename ?? /, :: ,) } LAST{ print /list\n } } This looks reasonable, but there's a bug. The CBETWEEN block can't decide whether to execute until it knows whether the loop is going to iterate again. And it can't know *that* until it has evaluated the condition again. At which point, the $filename variable has the wrong value. :-( The example is a little contrived perhaps, but it might be a common problem. For example, it happens here too: loop ($n=$from; $n$to; $n+=$skip) { print $page[$n]; BETWEEN { print Skipping to page $( $n+$skip )\n; } } C$n is updated before the conditional test, but the CBETWEEN block can't execute until after the conditional. Don't get me wrong: I *like* the idea of a BETWEEN block. I just think it's harder to get right (and *much* harder to explain) than most people would expect. Damian
Re: Loop controls
Luke Palmer [EMAIL PROTECTED] writes: On Tue, 30 Apr 2002, Miko O'Sullivan wrote: Damian, now having terrible visions of someone suggesting Celswhen ;-) Then may I also give you nightmares on: elsdo, elsdont, elsgrep, elstry ... Ooh! Why don't we have a dont command! With several variants: dont FILE dont BLOCK dont { print Boo } Hmm... what sort of semantics do you suggest? Just noop the following block? sub don't () { return } I really should get 'round to releasing the semi mythical Acme's::Abbreviations module. Here's a taster. I really hope that it won't be possible to perpetrate this sort of thing in Perl 6: package Acme's::Abbreviations; @ISA = 'Bloody Silly Thing To Do'; our $VERSION = '0.01'; sub can't { my $target = shift; if (UNIVERSAL::isa($target, 'UNIVERSAL')) { return ! $target-can(@_); } else { return ! UNIVERSAL::can($target, @_); } } *doesn't = \can't; sub isn't { my $target = shift; if (UNIVERSAL::isa($target, 'UNIVERSAL')) { return ! $target-isa(@_); } else { return ! UNIVERSAL::isa($target, @_); } } sub won't { my $target = shift; my $method = shift; eval { $target-can't($method) $target-can't('AUTOLOAD') }; } sub mightn't { my $target = shift; my $method = shift; eval { $target-can't($method) $target-can('AUTOLOAD') }; } sub mustn't { my $target = shift; my $method = shift; no strict 'refs'; my $old_glob = \ $ {${target}::}{$method}; delete $ {${target}::}{$method}; *{$target\::$method} = *{$old_glob}{$_} for (qw/ SCALAR HASH ARRAY IO /); 1; } # Preloaded methods go here. 1; -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: Loop controls
Damian said: 6. Cotherwise would seem to fit the bill rather nicely. To me, otherwise is a synonym for else, and that makes it too confusingly similar. I foresee forever explaining to people the difference between Celse and Cotherwise. I'm not sure if Cotherwise is popular because it is similar to Celse, but I think the similarity is a reason *not* to use it. How about Cnoloop? It's absolutely clear what it means and won't be confused with else. I now confidently await Larry's coming up with an entirely different solution ;-) I keep picturing Larry tugging thoughtfully on his mustache while reading this thread, a smile on his face, his finger hovering over the reveal button. -Miko
Re: Loop controls
Damian Conway wrote: Luke Palmer wrote: Ooh! Why don't we have a dont command! With several variants: dont FILE dont BLOCK dont { print Boo } Would print: You really *should* be more careful what you wish for Luke. The following was just uploaded to the CPAN... Damian -cut--cut--cut--cut--cut--cut- NAME Acme::Don't - The opposite of `do' VERSION This document describes version 1.00 of Acme::Don't, released May 1, 2002. SYNOPSIS use Acme::Don't; don't { print This won't be printed\n };# NO-OP DESCRIPTION The Acme::Don't module provides a `don't' command, which is the opposite of Perl's built-in `do'. AUTHOR Damian Conway ([EMAIL PROTECTED]) BLAME Luke Palmer really should be *far* more careful what he idly wishes for. BUGS Unlikely, since it doesn't actually do anything. However, bug reports and other feedback are most welcome. feature request : Acme::Dont::Obstruct We need a dont that will prevent *bad things*, to wit: dont ( 'let MS get away with it'); dont ( 'rape the planet'); dont ( 'sack ANWAR'); dont ( 'accept Bushs Energy Plan'); dont ('pass CBTBPTA*%#$'); in this light, your *impressive* module has the shortcoming that it cant stop stuff when its not used. Ex: W was able to hold secret energy meetings with the oil industry, w/o the participation of *any* environmental groups. Shades of Hillarys health plan that was pilloried. Wheres the uproar now ? Now the real trick will be getting this module to insert itself into code w/o explicit 'use' stuff it into universal ?? can you make a module that can do that ? huh ? huh ?
Re: Loop controls
Damian posted: NAME Acme::Don't - The opposite of `do' Wonderful job, Damian! I'll get to work on the complementary Acme::TryNotTo module. :-) -Miko
Re: Loop controls
On Wed, May 01, 2002 at 08:27:41AM -0400, Miko O'Sullivan wrote: Damian said: 6. Cotherwise would seem to fit the bill rather nicely. To me, otherwise is a synonym for else, and that makes it too confusingly similar. I foresee forever explaining to people the difference between Celse and Cotherwise. I'm not sure if Cotherwise is popular because it is similar to Celse, but I think the similarity is a reason *not* to use it. I actually think exactly the opposite. In my mind otherwise would just be a synonym for else so that loop { ... } else { ... } loop { ... } otherwise { ... } would both be syntactically valid. We would just encourage people to use the otherwise version for understandability. Since there's no difference between them, there's nothing to explain there, thus no confusion. Hmm. I wonder why the python community (apparently) have no problems with elses on loops: 7.2 The while statement The while statement is used for repeated execution as long as an expression is true: while_stmt ::= while expression : suite [else : suite] That's straight from http://www.python.org/doc/current/ref/while.html. If you read the page though, you'll see that their meaning isn't dwimmery at all. The else block is executed whenever the expression evaluates to false which could be if there's nothing to iterate over or just after the last iteration. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Loop controls
Jonathan said: I actually think exactly the opposite. In my mind otherwise would just be a synonym for else so that loop { ... } else { ... } loop { ... } otherwise { ... } would both be syntactically valid. I believe that the intention is that they *aren't* synonyms, i.e. they look similar but are different, leading to confusion. I imagine people who date twins sometimes kiss the wrong twin and *that* probably throws an exception. Same concept. -Miko
Re: Loop controls
Jonathan Scott Duff [EMAIL PROTECTED] wrote: Miko O'Sullivan wrote: Damian said: 6. Cotherwise would seem to fit the bill rather nicely. To me, otherwise is a synonym for else, and that makes it too confusingly similar. I foresee forever explaining to people the difference between Celse and Cotherwise. I'm not sure if Cotherwise is popular because it is similar to Celse, but I think the similarity is a reason *not* to use it. I don't care about the similarity in meaning, the visual distinction would be nice though. I actually think exactly the opposite. In my mind otherwise would just be a synonym for else so that loop { ... } else { ... } loop { ... } otherwise { ... } would both be syntactically valid. We would just encourage people to use the otherwise version for understandability. Since there's no difference between them, there's nothing to explain there, thus no confusion. This now becomes confusing (to me): if ($foo = 'bar') { loop { ... } else { ... } } and this insane: loop { ... } else { ... } if ...; Where if you intent say the normal 1-3 times then it might be VERY confusing to see mixed conditionals and loops. I think the fall through (currently mumbled as 'otherwise') should be a different keyword to make it visually distinct. I suspect Larry has the solution. Anyone who hasn't seen virtually impossible to avoid intents to the 6th (or thereabouts) level should email me for a sample. The Games::Golf, _unix_capture() method has them because it's combining signals (requiring double eval), IPC::Open3 and limits (on output length, time etc). I should make this a plea for a bugfix team, it's riddled with them. ;-) However, the currect interface for IO::Select and this loop/otherwise type construct would be great fun. Whenever it's included, can someone please travel back in time and put in into Perl 5, please? Hmm. I wonder why the python community (apparently) have no problems with elses on loops: I hazard a guess that facist whitespace rules have something to do with it. Jonatha Paton __ Do You Yahoo!? Everything you'll ever need on one web page from News and Sport to Email and Music Charts http://uk.my.yahoo.com
Re: Loop controls
In the true sprirt of perverseness, why not make loops into functions that return the number of iterations taken. Then you can have loop { } or die loop not taken\n; ;-) -- A walk of a thousand miles begins with a single step... then continues for another 1,999,999 or so.
Re: Loop controls
On Wed, May 01, 2002 at 04:14:49PM +0100, Dave Mitchell wrote: In the true sprirt of perverseness, why not make loops into functions that return the number of iterations taken. Then you can have loop { } or die loop not taken\n; ;-) Right. This was my initial idea; the else/otherwise stuff is too confusing as it hints too strongly to if blocks. So loop { ... } or print Sorry\n; loop { ... } or { print Sorry\n; # do other stuff } loop { ... } and print Done\n; The point is that it gives you the option to easily do something after the loop with the knowledge of whether the loop failed or succeeded, and it makes more grammatical sense, too. (loop/else doesn't.) :) marius. -- A walk of a thousand miles begins with a single step... then continues for another 1,999,999 or so.
Re: Loop controls
On Wed, May 01, 2002 at 09:03:42AM -0500, Jonathan Scott Duff wrote: Hmm. I wonder why the python community (apparently) have no problems with elses on loops: 7.2 The while statement The while statement is used for repeated execution as long as an expression is true: while_stmt ::= while expression : suite [else : suite] That's straight from http://www.python.org/doc/current/ref/while.html. If you read the page though, you'll see that their meaning isn't dwimmery at all. The else block is executed whenever the expression evaluates to false which could be if there's nothing to iterate over or just after the last iteration. If you abstract the meaning of Celse to execute when the condition in the previous block is false this makes perfect sense. It's just not very useful. This is actually a good reason for Perl to use a different keyword than else with loops. You avoid that interpretation entirely. You also avoid totally annoying Pythonists who occasionally use (and might be converted to) Perl. :) Allison
Re: Loop controls
On Wed, May 01, 2002 at 04:22:29PM +1000, Damian Conway wrote: NAME Acme::Don't - The opposite of `do' DESCRIPTION ... Note that the code in the `don't' block must be syntactically valid Perl. This is an important feature: you get the accelerated performance of not actually executing the code, without sacrificing the security of compile-time syntax checking. Um... I know it's scary, but I can actually imagine using this (or something like this) in development. I'll occasionally work on a section of code I'm not ready to integrate yet. It would be nice to be able to syntax check it without uncommenting and re-commenting the whole thing. :) Allison
Re: Loop controls
At 11:44 AM 5/1/2002 -0500, Allison Randal wrote: On Wed, May 01, 2002 at 04:22:29PM +1000, Damian Conway wrote: NAME Acme::Don't - The opposite of `do' DESCRIPTION ... Note that the code in the `don't' block must be syntactically valid Perl. This is an important feature: you get the accelerated performance of not actually executing the code, without sacrificing the security of compile-time syntax checking. Um... I know it's scary, but I can actually imagine using this (or something like this) in development. I'll occasionally work on a section of code I'm not ready to integrate yet. It would be nice to be able to syntax check it without uncommenting and re-commenting the whole thing. :) Doesn't if(0) do the job? :) -Melvin
Re: Loop controls
On Wed, May 01, 2002 at 12:53:39PM -0400, Melvin Smith wrote: At 11:44 AM 5/1/2002 -0500, Allison Randal wrote: Um... I know it's scary, but I can actually imagine using this (or something like this) in development. I'll occasionally work on a section of code I'm not ready to integrate yet. It would be nice to be able to syntax check it without uncommenting and re-commenting the whole thing. :) Doesn't if(0) do the job? :) Yes, as does Cwhile(0), and I've used them, though usually only when I eventually plan on putting in a real condition later. They don't stand out from the regular flow of control very well. Cdont would. No. I don't think we need Cdont. I'm *not* saying that. I'm just having fun with the idea. :) Allison
Re: Loop controls
On Wed, 2002-05-01 at 08:27, Miko O'Sullivan wrote: Damian said: 6. Cotherwise would seem to fit the bill rather nicely. To me, otherwise is a synonym for else, and that makes it too confusingly similar. I foresee forever explaining to people the difference between Celse and Cotherwise. I'm not sure if Cotherwise is popular because it is similar to Celse, but I think the similarity is a reason *not* to use it. How about Cnoloop? It's absolutely clear what it means and won't be confused with else. Call it maxheadroom for all it will matter. * people will still see conditional execution associated with loops * the unless/elsif syntax is still grotesque and asymmetric * the treatment of conditionals{1} vs conditionals{1,} is asymmetric If you un-peel this and expose the elegant simplicity of flow control, you can unify all of these concepts to their basic form: flowcontrol: controlblock | controlblock TOK_else flowcontrol | controlblock TOK_else block ; controlblock: controlword expression closure | controlword expression block | TOK_loop block | TOK_loop expression ';' expression ';' expression block ; controlword: TOK_if | TOK_unless | TOK_while | TOK_until | TOK_for | TOK_when ; block: '{' statements '}' ; closure: mumble... ; expression: mumble... ; statements: mumble... ; I haven't really thought about this representation of the grammar much, and I'm not grammar constructor by nature, but you can see the idea here, and the stark simplicity of it. What is so lovely about elsif that we cling to it, and mutate the admittedly obvious choices elsewhere to preserve it?
Re: Loop controls
On Wed, 2002-05-01 at 12:22, Allison Randal wrote: On Wed, May 01, 2002 at 09:03:42AM -0500, Jonathan Scott Duff wrote: [... in python ...] while_stmt ::= while expression : suite [else : suite] That's straight from http://www.python.org/doc/current/ref/while.html. If you abstract the meaning of Celse to execute when the condition in the previous block is false this makes perfect sense. It's just not very useful. This is actually a good reason for Perl to use a different keyword than else with loops. You avoid that interpretation entirely. You also avoid totally annoying Pythonists who occasionally use (and might be converted to) Perl. :) So, the Python while is the Perl6: loop { if (expression) { suite } else { suite last; } } This is not shocking at all, as Python does not dip into the polymorphism of containers nearly so much as Perl does. To Python, evaluating the truth of a sequence of this type requires there to be a truth already present. In this case, the truth of the last evaluation of the expression suffices. Perl is fundamentally different in its approach and just as a Pythoner will have to swallow hard and squint to understand other polymorphic and context-sensitive aspects of Perl containers, so too will they have to get over this distinction. I'm not slighting Python here. I'm just saying that there's a learning curve fraught with dangerous similarities in both directions, and constructing Perl to accommodate that transition does not seem to be particularly wise.
Re: Loop controls
On Wed, May 01, 2002 at 02:47:56PM -0400, Aaron Sherman wrote: On Wed, 2002-05-01 at 12:22, Allison Randal wrote: You also avoid totally annoying Pythonists who occasionally use (and might be converted to) Perl. :) ... Perl is fundamentally different in its approach and just as a Pythoner will have to swallow hard and squint to understand other polymorphic and context-sensitive aspects of Perl containers, so too will they have to get over this distinction. I'm not slighting Python here. I'm just saying that there's a learning curve fraught with dangerous similarities in both directions, and constructing Perl to accommodate that transition does not seem to be particularly wise. Yes, accommodating Pythonies is not a good primary reason for using a different keyword. But it's a nice side benefit of what seems to be the best option (so far) for independent reasons (Damian's post summed up and solidified the discussion quite nicely). Allison
Re: Loop controls
Damian said: The CBETWEEN block can't decide whether to execute until it knows whether the loop is going to iterate again. And it can't know *that* until it has evaluated the condition again. At which point, the $filename variable has the wrong value. :-( The example is a little contrived perhaps, but it might be a common problem. I don't think your example is contrived at all. It's just a situation where a little education is all that's needed. The rule could be quite simple: BETWEEN is run before every iteration except for the first iteration. Any variables that you use in BETWEEN are for the iteration that is about to run, not the iteration that just ran. Once people gt that concept things become clear. However, it was because of your conundrum that I first proposed that Cbetween (not CBETWEEN) is put after the loop. To me that makes it absolutely clear that between isn't part of any one iteration: while whatever() { ... } between { ... } I should admit, however, that this thread has made me prefer BETWEEN inside the block. It keeps open the possibility of loops becoming part of if-elsif chains, even if it's not the choice to allow that right now. -Miko
Re: Loop controls
I now realize that my previous message was a little hard to read (plus I sounded a bit harsh, which I did not mean to be, I was just excited, thinking about this), because I insisted on being sort of stilted in my pseudo-BNF. Here's a cleaner shot at what I meant: flow: control 'else' flow | control 'else' block | control ; control: controlkey expr '-' closuredef | controlkey expr block | 'loop' block | 'loop' expr ';' expr ';' expr block ; controlkey: 'if' | 'unless' | 'while' | 'until' | 'for' | 'when' ; block: '{' statements '}' That should be a bit easier to appreciate. I find myself looking at this and loving Perl just a little bit more Again, my example from before: unless my $fh = $x.open { die Cannot open $x: $!; } else while $fh.getline - $_ { print; } else { die No lines to read in $x; } That does seem to roll of the tongue, does it not?
Re: Loop controls
On Wed, May 01, 2002 at 05:08:14PM -0400, Miko O'Sullivan wrote: Damian said: The CBETWEEN block can't decide whether to execute until it knows whether the loop is going to iterate again. And it can't know *that* until it has evaluated the condition again. At which point, the $filename variable has the wrong value. :-( The example is a little contrived perhaps, but it might be a common problem. I don't think your example is contrived at all. It's just a situation where a little education is all that's needed. The rule could be quite simple: BETWEEN is run before every iteration except for the first iteration. Any variables that you use in BETWEEN are for the iteration that is about to run, not the iteration that just ran. Once people gt that concept things become clear. You know, I almost made a very similar reply. But I read through Damian's message a second time and changed my mind. CBETWEEN makes sense as a CNEXT minus CLAST. As a CPRE minus CFIRST it's less appealing. At the very least it begs a different name than BETWEEN (a name that implies it executes between each loop, not at the beginning of some). Hmmm... would CLAST not have the same problem as CBETWEEN? It also can't decide whether to execute until it knows whether the loop is going to iterate again. Allison
Re: Loop controls
Damian, now having terrible visions of someone suggesting Celswhen ;-) Then may I also give you nightmares on: elsdo, elsdont, elsgrep, elstry ... :-) -Miko
Re: Loop controls
On Tue, 30 Apr 2002, Miko O'Sullivan wrote: Damian, now having terrible visions of someone suggesting Celswhen ;-) Then may I also give you nightmares on: elsdo, elsdont, elsgrep, elstry ... Ooh! Why don't we have a dont command! With several variants: dont FILE dont BLOCK dont { print Boo } Would print: Luke
Re: Loop controls
On Tuesday, April 30, 2002, at 01:22 PM, Dan Sugalski wrote: At 1:07 PM -0400 4/30/02, Miko O'Sullivan wrote: Damian, now having terrible visions of someone suggesting Celswhen ;-) Then may I also give you nightmares on: elsdo, elsdont, elsgrep, elstry ... Has anyone brought up elselse or unlessunless yet? All of this is a bit silly, but if loops in Perl6 had some sort of boolean value of their own, then it seems the language already has a way to approach this. Scoping might be a problem, but... for foo - $bar { ... } // print The loop didn't... uh... loop.\n; Just a thought.
Re: Loop controls
On Tue, 2002-04-30 at 13:07, Miko O'Sullivan wrote: Damian, now having terrible visions of someone suggesting Celswhen ;-) Then may I also give you nightmares on: elsdo, elsdont, elsgrep, elstry ... Aaron, trying hard not to be a crackpot, but getting the impression that's now just a dream :-/ If we all agree that the meaning of elsflow-control-keyword is clear, but we dislike adding insane numbers of keywords to the language, let's step back and ask why it would have ever occurred to us to do such a silly thing. Since the beginning of this discussion, I've been happy to accept the idea that elswhile is ugly and unmanageable, but I saw no other way, given the if/elsif syntax. I do think that unifying the if/loop syntax is wildly useful, but there's no reason that we HAVE to put the burden on the loop constructs. Why do we use elsif? Well, it seemed like the right choice at the time, and avoided C's infamous ambiguity by allowing braces without bogging down the programmer (Larry, jump in if that wasn't the reasoning, it's been nearly a decade since I last saw you discuss the topic). What would happen if we had: if expr { ... } else if expr { ... } else { ... } Not as a naked (i.e. un-braced) statement, but if else if were treated as a single token (either at the tokenizer level or gathered together in the parser, it doesn't really matter). In this case, you could have all of the funky control structures you want, but the user does not have to play string-concatenation games in their head. It's reasonably obvious what: unless my $fh=$x.open { die Cannot open $x: $!; } else while $fh.getline - $_ { print; } else { die No lines to read from $x; } would mean, and it's also a pleasingly simple addition. Then if you want else when or else do, you're all set. It's an easy change and there are no new keywords. I think else grep would be pointless, as grep is not a flow-control structure as such. You can always else if grep {...} list { ... } This also resolves the long-standing question: why isn't there an elsunless, which has been asked since as long as I've been programming in Perl. I see no reason for there not to be else unless, does anyone else? unless?
Re: Loop controls
Why not allow Celse if while still allowing Celsif as a synonym, preserving backwards compatibility while still allowing all these weird and varied constructs people seem to have use for? In any case, I don't really see why Cloop...else necessarily implies all these other cases, too. Maybe they're useful in the real world, maybe they're not, but Cloop...else itself is pretty clearly useful. Perhaps it's just the type of work I do (system administration), but dealing with the zero records problem is something I have to do in nearly every program I write, and it always adds an annoyingly inelegant bit of code. I paste from a bit of code I wrote about a year before this discussion got started... my $recs = 0; while (my $this = $db-getNext()) { ... $recs++; } unless ($recs) { # because while can't tell me it didn't loop... Now maybe Cwhile can. Hurray! I'd hate to lose such a nice construction as Cloop...else just because of the slippery slope argument implied by Celsloop, etc. Anyone who's taken oratory or participated in high school debate teams should know that slippery slope arguments are always fallacious. :-) Trey
Re: Loop controls
On Tue, 30 Apr 2002, Trey Harris wrote: Why not allow Celse if while still allowing Celsif as a synonym, preserving backwards compatibility while still allowing all these weird and varied constructs people seem to have use for? Backwards compatability is pretty much a lost cause for Perl 6. You could argue that it's good to keep the people who are used to it happy, but in this case I don't think that's necessary. p52p6 should do all the backwards compatability work. Luke
Re: Loop controls
In a message dated Tue, 30 Apr 2002, Luke Palmer writes: On Tue, 30 Apr 2002, Trey Harris wrote: Why not allow Celse if while still allowing Celsif as a synonym, preserving backwards compatibility while still allowing all these weird and varied constructs people seem to have use for? Backwards compatability is pretty much a lost cause for Perl 6. You could argue that it's good to keep the people who are used to it happy, but in this case I don't think that's necessary. p52p6 should do all the backwards compatability work. Oops, sorry. I didn't really mean backwards compatibility. I meant convention. Celsif could still be the preferred way of writing it, while actually being a synonym for Celse if. Even if there's a rationale here, I think we're really getting in to the realm of gratuitious changes (in the eyes of most Perl 5-6 migrants) if Celsif changes to Celse if. Trey
Re: Loop controls
Then if you want else when or else do, you're all set. It's an easy change and there are no new keywords. Agree with everything else you said. One minor question: how would else do be different than else? do always does, doesn't it? -Miko
Re: Loop controls
so, assuming we have; print 'you gave me: wordlist = ';# single quote - no interpolation for words - $it { print; FIRST { print '(' }# provisionally NEXT { print ',' } LAST {print ');' } } # and maybe else { print ();\n; } this yields: you gave me: wordlist = (); or if (wordlist) { # (damn - i want to say orif ;-) you gave me: wordlist = (alpha,beta,gamma,); whereas print 'you gave me: wordlist = (', join(',', words), )\n; doesnt include the last comma. if I remember the thread (now deleted, so cant be accurate) the last comma would be in there, unlike if it were in a join. cuz NEXT is a block terminator, not a block-inbetweener this is vaguely unfortunate, as its not so simple to write loops to generate SQL ( which isnt as friendly wrt to extra commas as perl is ) separately ( to re-iterate earlier good thoughts ): loop {} else {} would be more visually distinct (easier to read) as loop {} otherwize {} esp when loop block is bigger than a screenful, new keyword keeps us from looking for the if, and it fits better with natural language (or at least dictionary language ) where the connotation is a final alternative to lots of choices. http://webster.com/cgi-bin/dictionary?va=otherwise Main Entry: *^1 oth·er·wise* javascript:popWin('/cgi-bin/audio.pl?otherw04.wav=otherwise') Pronunciation: -wIz Function: /pronoun/ Etymology: Middle English, from Old English (/on/) /Othre wIsan / in another manner Date: before 12th century *:* something or anything else *:* something to the contrary do very little to enforce competition--and have never intended /otherwise/ -- Milton Viorst vs Main Entry: *^1 if* javascript:popWin('/cgi-bin/audio.pl?if01.wav=if') Pronunciation: 'if, f Function: /conjunction/ Etymology: Middle English, from Old English /gif; /akin to Old High German /ibu /if Date: before 12th century *1 a* *:* in the event that *b* *:* allowing that * c* *:* on the assumption that *d* *:* on condition that *2* *: WHETHER http://webster.com/cgi-bin/dictionary?book=Dictionaryva=whether* asked /if/ the mail had come I doubt /if/ I'll pass the course *3* -- used as a function word to introduce an exclamation expressing a wish /if/ it would only rain *4* *:* even though an interesting /if/ untenable argument - *if anything* *:* on the contrary even *:* perhaps even /if anything, /you ought to apologize look ma, no typing..
Re: Loop controls
On Tue, 30 Apr 2002, Jim Cromie wrote: so, assuming we have; print 'you gave me: wordlist = ';# single quote - no interpolation for words - $it { print; FIRST { print '(' }# provisionally NEXT { print ',' } LAST {print ');' } } # and maybe else { print ();\n; } this yields: you gave me: wordlist = (); or if (wordlist) { # (damn - i want to say orif ;-) you gave me: wordlist = (alpha,beta,gamma,); whereas print 'you gave me: wordlist = (', join(',', words), )\n; doesnt include the last comma. if I remember the thread (now deleted, so cant be accurate) the last comma would be in there, unlike if it were in a join. cuz NEXT is a block terminator, not a block-inbetweener this is vaguely unfortunate, as its not so simple to write loops to generate SQL ( which isnt as friendly wrt to extra commas as perl is ) I'd rather have an in-betweener block too. Loops like this are very common, and I hate doing prefix commas, if you know what I mean. I realize NEXT often used for cleanup, so maybe you could introduse Yet Another block, BETWEEN (or SQUEEZE). Or are we just going to have to deal with this fact? separately ( to re-iterate earlier good thoughts ): loop {} else {} would be more visually distinct (easier to read) as loop {} otherwize {} It would be especially clear if it were spelled correctly ;) esp when loop block is bigger than a screenful, new keyword keeps us from looking for the if, and it fits better with natural language (or at least dictionary language ) where the connotation is a final alternative to lots of choices. Yes, I think that's a good idea also. I suppose Celse DWIMs better though (I've taught people C++, and many times they wonder why they can't put elses on loops). I think it's really a matter of opinion. Which is, I suppose, why this list is here. Luke
Re: Loop controls
Dan Sugalski wrote: At 1:07 PM -0400 4/30/02, Miko O'Sullivan wrote: Damian, now having terrible visions of someone suggesting Celswhen ;-) Then may I also give you nightmares on: elsdo, elsdont, elsgrep, elstry ... Has anyone brought up elselse or unlessunless yet? and since this line of conjecture keeps going, andif orif orelse
Re: Loop controls
Lots of people said: Lots of stuff about 'else' loops. *Erik thunks himself some deep thought* I see no true slippery slope here, especially if handled correctly. I suspect that an explicit or implicit why not near the beginning of discussion lead to the feature feeding frenzy and the slippery slope responses. To my thinking, assuming this is a needed feature, the ELSE block method is not quite adequate. We are approaching the limit to the number of implicit blocks within control structures a mind can be reasonably expected to handle. Although we have made comments on the placement of these blocks being hapahzard as is, there isn't necessarily a clear position within the flow of code that is associated with the concepts behind those blocks. 'ELSE' however seems to clearly need to be after the block to which it represents an alternative. Scoping issues also tend toward the post block syntax. The need for such a structure has been most clearly defined and argued for in the case of 'loop'. While others have said 'I can see advantages' I generally cannot, save in the case of loop where the synthetic code of the flag to check if the loop was passed through is a hassle and not clear. Allowing a 'loop {...} else {...}' syntax seems to fill this niche nicely. I have always argued that any exceptions to the looping rules should be attatched to while, as while already had special behavior for DWIM. Now that loop has gained this behavior anyway, loop seems the most deserving canidate for that reason. Finally, scoping issues seem to have mostly to do with aliasing. While plenty of implicit aliasing occurs with 'loop {...}' explicit aliasing seems to occur with 'foreach'. By only allowing the else construct on the control structure least likely to have scoping issues, it makes the learning of the syntax easier. Even if you don't understand them, you're less likely to run into them. As far as implicit aliasing goes, I think that it would be clear that the else block only executes if $_ hasn't been assigned to by the diamond, making it unlikely anyone would be bit by subtle bugs from the use of $_ in the else block. I hope :-) So, all of these things seem to say to me that the case can be made for allowing 'loop' to have an 'else' block, and for no other structures to, and that this clock should work like an if block, and not like the implicit blocks already extant. -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: Loop controls
On Fri, 2002-04-26 at 19:06, Allison Randal wrote: On Fri, Apr 26, 2002 at 05:24:13PM -0400, Aaron Sherman wrote: Of course it brings other less wholesome things to mind like elsfor and elsloop and if ... elsfor and for ... elsif ... elsloop ... else, but why not? Urk. And why? Besides, I would expect an Celsfor to actually be a loop of it's own, on the principle of elsif = else + if so elsfor = else + for. Absolutely what I thought. elsif would be for thing else if where elsfor would be thing else for-loop. Since you got this distinction right off, it sounds like an intuitive enough syntax. Yes, but there's a difference with Cwhile in that you wouldn't want an else to execute anytime the Cwhile came across a false value, but only if the *first* value it came across was false (i.e. only if the loop isn't going to execute at all). Otherwise, you'd just use a LAST block (a parallel that I think argues for ELSE blocks). This is just going up a level in terms of what you're looking at. If I wrote this: if (!grep {$_ eq 'foo'} bar) { ... } You wouldn't find it confusing that the block only executes if NO element of the array bar is 'foo'. So, this should not be confusing either: $i=0; loop ;$i$max;$i++ { ... } else { ... } In this case, if $max = 0, then you will execute the else. And Cfor and Cloop are even more different. You could kind of stretch the point and say that the evaluation of the second expression is the false value, I'll give you that. But it still has the same problem as Cwhile. $i = $somevalue; # possibly set by user input to 5 or higher ... loop ; $i 5; $i++ { ... } And where's the false value here? The else would be more of no values to iterate over. Again, it's just first derivative over time. You're not asking is there a false value, you're asking is the loop false. Just as we understand that an array in a conditional context is false if it is empty, so too is a loop false if it is empty. This is a basic Perl concept, and it makes sense to promote it from static arrays to more dynamic loops. I can also think of some advantages to having the else within the scope of the loop. while alllines(/etc/passwd) - $_ { ... } else { die /etc/passwd: $_; } But the aliased value, $_, is restricted to the scope of the Cwhile's block, it isn't going to be accessible in the block associated with the Celse (you would be getting some $_ from an outer scope). You're thinking of loops in a curious and convoluted way, Try this out: { loop-keyword [ conditional/declaration ] block { else-clauses ...} } The loop itself comprises an outer scope in which the conditionals or declarations exist. Then, each block comprises a sub-scope. In this way, there is no confusion, no special case, no violation of the rules. It becomes reasonable now to have: for a - $b { stuff using $b } elsfor c - $d { more stuff using $b and $d } else { yet further stuff with access to $b and $d } And what a neophyte programmer might expect about access to variables is all true.
Re: Loop controls
On Fri, 2002-04-26 at 19:30, Miko O'Sullivan wrote: Of course it brings other less wholesome things to mind like elsfor and elsloop and if ... elsfor and for ... elsif ... elsloop ... else, but why not? Well, I agree with the concept, but boyoboy those names ain't gonna fly. We'll have to head down the road of unlessfor Why? We don't have an unlessif, why would we ever have unlessfor?! elseuntil I would expect that to be elsuntil, but as we're dropping until from the language, it's a moot point. unlessuntil See above. Two issues spring to mind: 1) Do we have a reality check on why this syntax is needed? I agree it's cool idea, but can anyone name a real-world scenario where it would be useful? Can we do things just bcause they're cool? That approach didn't work too well for me as a teenager, but then nothing else did either. It's not because it's cool. It's because the alternative is: Perl5: $did = 0; for($i=0;$i$max;$i++) { ... } unless ($did) { foreach (x) { ... } } Perl6: loop $i=0;$i$max;$i++ { ... ELSE { for x - $_ { ... } } } Proposed Perl6: loop $i=0;$i$max;$i++ { ... } elsfor x - $_ { ... } Points for last option: 1. Cleaner code 2. Scope is cleaner. Why does the we never executed this block code, have to exist inside of the block's scope? What are we preserving? At the very least, moving the else out of the block makes sense, but I think preserving elsif is useful as well. The fact that that calls for the possibility of elsfor, elseloop, etc, is IMHO just a nice extra.
RE: Loop controls
On Monday, April 29, 2002 3:10 PM, Aaron Sherman wrote: On Fri, 2002-04-26 at 19:06, Allison Randal wrote: On Fri, Apr 26, 2002 at 05:24:13PM -0400, Aaron Sherman wrote: Of course it brings other less wholesome things to mind like elsfor and elsloop and if ... elsfor and for ... elsif ... elsloop ... else, but why not? Urk. And why? Besides, I would expect an Celsfor to actually be a loop of it's own, on the principle of elsif = else + if so elsfor = else + for. Absolutely what I thought. elsif would be for thing else if where elsfor would be thing else for-loop. Since you got this distinction right off, it sounds like an intuitive enough syntax. It's a hideous syntax. grin If things go in this direction, it seems cleaner to permit Celse to be followed by certain statements; Cif, Cfor, Cunless, Cloop, et al., avoiding adding many (ugly!) keywords to the language. Philip, who's always preferred 'else if' despite the extra keystrokes. Disclaimer This communication together with any attachments transmitted with it ('this E-mail') is intended only for the use of the addressee and may contain information which is privileged and confidential. If the reader of this E-mail is not the intended recipient or the employee or agent responsible for delivering it to the intended recipient you are notified that any use of this E-mail is prohibited. Addressees should ensure this E-mail is checked for viruses. The Carphone Warehouse Group PLC makes no representations as regards the absence of viruses in this E-mail. If you have received this E-mail in error please notify our ISe Response Team immediately by telephone on + 44 (0)20 8896 5828 or via E-mail at [EMAIL PROTECTED] Please then immediately destroy this E-mail and any copies of it. Please feel free to visit our website: UK http://www.carphonewarehouse.com Group http://www.phonehouse.com
Re: Loop controls
On Mon, Apr 29, 2002 at 10:26:26AM -0400, Aaron Sherman wrote: I would expect that to be elsuntil, but as we're dropping until from the language, it's a moot point. Er, what?!? Who said we're dropping until? Did I miss something? Proposed Perl6: loop $i=0;$i$max;$i++ { ... } elsfor @x - $_ { ... } Hrm. Do you also propose an elsloop too? I think a general else or otherwise on all loops allows what you want: loop $i = 0; $i $max; $i++ { ... } else { for @x { ... } } And is just as clear. Or if the new for, if, while, etc. constructs can be somehow generate a code reference, maybe we can write it this way: loop $i = 0; $i $max; $i++ { ... } else for @x { ... } loop $i = 0; $i $max; $i++ { ... } else while ($x 5) { ... } -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Loop controls
See above. Two issues spring to mind: 1) Do we have a reality check on why this syntax is needed? I agree it's cool idea, but can anyone name a real-world scenario where it would be useful? Can we do things just bcause they're cool? That approach didn't work too well for me as a teenager, but then nothing else did either. It's not because it's cool. It's because the alternative is: Perl5: $did = 0; for($i=0;$i$max;$i++) { ... } unless ($did) { foreach (x) { ... } } Perl6: loop $i=0;$i$max;$i++ { ... ELSE { for x - $_ { ... } } } Proposed Perl6: loop $i=0;$i$max;$i++ { ... } elsfor x - $_ { ... } How's about we set up parsing such that a conditional or loop control structure can be placed after an else. That would provide the most versatility, reduce the hideous keywords, and be more familiar to C programmers. loop $i=0;$i$max;$i++ { ... } else for x- $_ { ... } Oh, and why are we dropping Cuntil from the language? If we drop Cuntil, we should drop unless, and that's just preposterous. Luke
Re: Loop controls
On Sat, 2002-04-27 at 01:14, Luke Palmer wrote: On Fri, 26 Apr 2002, Allison Randal wrote: Besides, I would expect an Celsfor to actually be a loop of it's own, on the principle of elsif = else + if so elsfor = else + for. So, you're suggesting we add Celsunless then? Just because it's possible doesn't mean it's necessary. Not a bad idea. It doesn't strike me as being quite as helpful as the conditional loops, but you could probably talk me into it.
Re: Loop controls
On Mon, Apr 29, 2002 at 10:10:01AM -0400, Aaron Sherman wrote: On Fri, 2002-04-26 at 19:06, Allison Randal wrote: Absolutely what I thought. elsif would be for thing else if where elsfor would be thing else for-loop. Since you got this distinction right off, it sounds like an intuitive enough syntax. I'll vote with the others on this. The meaning is only partially intuitive when you read it. You'll notice that I thought *you* meant that elsfor would be an else (i.e. a conditional) tacked onto a Cfor. And as far as using it, I'd rather not memorize (and teach) dozens of compound keywords and all their subtle nuances when simple control structures will do. So, this should not be confusing either: $i=0; loop ;$i$max;$i++ { ... } else { ... } In this case, if $max = 0, then you will execute the else. I agree. Again, it's just first derivative over time. You're not asking is there a false value, you're asking is the loop false. Just as we understand that an array in a conditional context is false if it is empty, so too is a loop false if it is empty. This is a basic Perl concept, and it makes sense to promote it from static arrays to more dynamic loops. I agree again. There will have to be a section of the training material devoted to When is a loop false? (I like that perspective, it nicely unifies the cases), but it should be a short one. But the aliased value, $_, is restricted to the scope of the Cwhile's block, it isn't going to be accessible in the block associated with the Celse (you would be getting some $_ from an outer scope). You're thinking of loops in a curious and convoluted way, Try this out: { loop-keyword [ conditional/declaration ] block { else-clauses ...} } The loop itself comprises an outer scope in which the conditionals or declarations exist. Then, each block comprises a sub-scope. In this way, there is no confusion, no special case, no violation of the rules. Not so much convoluted as literal-minded on lexical scope being tied to blocks: { {} } is not the same as { } { }. It could be made to work, but it would be an exception to Perl's general take on lexical scope. It becomes reasonable now to have: for a - $b { stuff using $b } elsfor c - $d { more stuff using $b and $d } else { yet further stuff with access to $b and $d } And what a neophyte programmer might expect about access to variables is all true. Except that, as Damian pointed out, if the Cfor is false $b will never be aliased at all. Allison
Re: Loop controls
On Mon, 2002-04-29 at 10:41, Jonathan Scott Duff wrote: On Mon, Apr 29, 2002 at 10:26:26AM -0400, Aaron Sherman wrote: I would expect that to be elsuntil, but as we're dropping until from the language, it's a moot point. Er, what?!? Who said we're dropping until? Did I miss something? Well, if there's no while (replaced by generic loop, per Apoc4) why would there be an until? Proposed Perl6: loop $i=0;$i$max;$i++ { ... } elsfor x - $_ { ... } Hrm. Do you also propose an elsloop too? I think a general else or otherwise on all loops allows what you want: Ok, once more for those in the cheap seats (no offense, it's just a lot of people seemed to have ignored the thread until now and jumped in without the context), this is how we got here: 1. Larry says loops will have ELSE blocks inside them. 2. Someone suggests loop {} else {} 3. Someone else points out that that's bad, because people will expect elsif 4. I point out that elsif isn't so bad, and perhaps there should be an array of other else options. So, the answer to your question is: yes, I do propose that there should be an elsif, elsloop and elsfor. That's it. Three words, not an expansive list of ever-more-complex words. Now, I agree that else for might make more sense, but it's very ugly on the grammar (given that we don't allow free statements like C does).
Re: Loop controls
On Mon, Apr 29, 2002 at 10:26:26AM -0400, Aaron Sherman wrote: On Fri, 2002-04-26 at 19:30, Miko O'Sullivan wrote: 1) Do we have a reality check on why this syntax is needed? It's because the alternative is: Perl5: $did = 0; for($i=0;$i$max;$i++) { ... } unless ($did) { foreach (x) { ... } } Perl6: loop $i=0;$i$max;$i++ { ... ELSE { for x - $_ { ... } } } Proposed Perl6: loop $i=0;$i$max;$i++ { ... } elsfor x - $_ { ... } You left off possibility #4: loop $i=0;$i$max;$i++ { ... } else { for x - $_ { ... } } At first glance I kind of like possibility #5: loop $i=0;$i$max;$i++ { ... } else for x - $_ { ... } But you still have the added complexity of which keywords can be used that way. And you've only saved two curly braces. Allison
Re: Loop controls
Well, if there's no while (replaced by generic loop, per Apoc4) why would there be an until? Whoa. I actually had a moment of panic there. Then I checked for myself. I don't see anything in Apoc4 about getting rid of while. It may be excluded from evolution, but it's still there, sorta like the alligator. Larry uses while in several examples. So, the answer to your question is: yes, I do propose that there should be an elsif, elsloop and elsfor. That's it. Three words, not an expansive list of ever-more-complex words. Why not also elswhile? According to Apoc4, while still gets the cool loop controls like NEXT, why shouldn't it get to join the els party? Even alligators evolve a little. BTW, like so much in Perl, I found elsfor etc. ugly at first, then I grew to like it. Is it really that lexically nonsensical? -Miko
Re: Loop controls
On Sat, 2002-04-27 at 08:53, Damian Conway wrote: Which I presume was that the proposed usage: while $result.get_next() - $next { # do something with $next... ELSE { if $next eq xyz572 { print We defined this value, $next, as false for obscure purposes.; print No loop was executed. Just wanted to let you know.; } } } would actually be a (very subtle and nasty) bug! I disagree. It has no bug (unless you want it to). I also thought while was gone, replaced by loop, but if while is in, then there's no bug. Here's the code, expanded: my $tmploop = sub ($next is rw) { # do something with $next... } my $tmpelse = sub ($next is rw) { print We defined this value, $next, as false for obscure purposes.; } { my $tmpval; my $loopcnt = 0; loop { $tmpval = $result.get_next(); last unless $tmpval; $loopcnt++; $tmploop.($tmpval); } $tmpelse.($tmpval) unless $loopcnt; } Now, if you put the temporary inside of the loop scope, then I have to agree with you: there's no $next when you get to the else, but that's not the only way to do it, and I really don't think you SHOULD do it that way. After all, you might have important reasons to want access to that value! If you're implying that putting the else outside the block should indicate that $next is no longer in scope, I disagree on the exact same grounds. I want the else to be outside, but the primary reason to me is that it's far cleaner looking code. Is there any reason to do it the other way?
Re: Loop controls
On Mon, Apr 29, 2002 at 03:30:40PM -0400, Aaron Sherman wrote: On Mon, 2002-04-29 at 10:41, Jonathan Scott Duff wrote: On Mon, Apr 29, 2002 at 10:26:26AM -0400, Aaron Sherman wrote: I would expect that to be elsuntil, but as we're dropping until from the language, it's a moot point. Er, what?!? Who said we're dropping until? Did I miss something? Well, if there's no while (replaced by generic loop, per Apoc4) why would there be an until? Larry didn't say loop was replacing while. He said that the magic do {} while was going away to be replaced by loop. while and until (both as loops and modifiers) will still be around AFAIK. 1. Larry says loops will have ELSE blocks inside them. Did he say that? Or was it inferred from NEXT, LAST, etc. by others? 4. I point out that elsif isn't so bad, and perhaps there should be an array of other else options. And I say, why have several specific things when you can have 1 generalized thing that does the same job. (I'm not going to describe it beyond that. It's up to Larry+Damian to define the shape of the thing) So, the answer to your question is: yes, I do propose that there should be an elsif, elsloop and elsfor. That's it. Three words, not an expansive list of ever-more-complex words. You're just weird. :) Now, I agree that else for might make more sense, but it's very ugly on the grammar (given that we don't allow free statements like C does). Hey, perl 6 is supposed to be optimized for the programmer, not the perl parser ;-) -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Loop controls
On Mon, Apr 29, 2002 at 03:30:40PM -0400, Aaron Sherman wrote: Ok, once more for those in the cheap seats (no offense, it's just a lot of people seemed to have ignored the thread until now and jumped in without the context), this is how we got here: 1. Larry says loops will have ELSE blocks inside them. 2. Someone suggests loop {} else {} Um... actually Allison brought in the ELSE blocks. I mean, I appreciate the complement, but I'm hardly Larry. ;) And this was after Damian indicated we might have Celse on loops. 3. Someone else points out that that's bad, because people will expect elsif 4. I point out that elsif isn't so bad, and perhaps there should be an array of other else options. I still don't like the idea of Celsifs on loops. I already do an instant double take with Celse of Where's the if? (with visions of old Wendy's commercials dancing in my head). It seems that a long string of Celsifs (possibly separated by other long intervening sections of code) would make the expectation even stronger when I was trying to read through someone's code. But, that is a matter of habit and could be retrained. Allison
Re: Loop controls
On Mon, 2002-04-29 at 15:46, Miko O'Sullivan wrote: Well, if there's no while (replaced by generic loop, per Apoc4) why would there be an until? Whoa. I actually had a moment of panic there. Then I checked for myself. I don't see anything in Apoc4 about getting rid of while. It may be excluded from evolution, but it's still there, sorta like the alligator. Larry uses while in several examples. Ok, going back and looking, I was mislead by a bad memory. I had asked if for(;;) was still in, and Larry pointed out that it was, but it was now loop;; So, the answer to your question is: yes, I do propose that there should be an elsif, elsloop and elsfor. That's it. Three words, not an expansive list of ever-more-complex words. Why not also elswhile? According to Apoc4, while still gets the cool loop controls like NEXT, why shouldn't it get to join the els party? Even alligators evolve a little. If there's a while, there should be an elswhile. My bad on the mix-up.
Re: Loop controls
On Mon, Apr 29, 2002 at 02:55:09PM -0500, Allison Randal wrote: I still don't like the idea of Celsifs on loops. I already do an instant double take with Celse of Where's the if? (with visions of old Wendy's commercials dancing in my head). Me too. That's why the looping else should be spelled otherwise IMHO. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Loop controls
What about unless? Since we are giving els to loops, shouldn't we upgrade unless as well? That would be really weird if it were not upgraded. Tanton - Original Message - From: Jonathan Scott Duff [EMAIL PROTECTED] To: Allison Randal [EMAIL PROTECTED] Cc: Aaron Sherman [EMAIL PROTECTED]; Perl6 Language List [EMAIL PROTECTED] Sent: Monday, April 29, 2002 4:01 PM Subject: Re: Loop controls On Mon, Apr 29, 2002 at 02:55:09PM -0500, Allison Randal wrote: I still don't like the idea of Celsifs on loops. I already do an instant double take with Celse of Where's the if? (with visions of old Wendy's commercials dancing in my head). Me too. That's why the looping else should be spelled otherwise IMHO. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Loop controls
On Mon, 2002-04-29 at 15:54, Jonathan Scott Duff wrote: On Mon, Apr 29, 2002 at 03:30:40PM -0400, Aaron Sherman wrote: On Mon, 2002-04-29 at 10:41, Jonathan Scott Duff wrote: On Mon, Apr 29, 2002 at 10:26:26AM -0400, Aaron Sherman wrote: I would expect that to be elsuntil, but as we're dropping until from the language, it's a moot point. Er, what?!? Who said we're dropping until? Did I miss something? Well, if there's no while (replaced by generic loop, per Apoc4) why would there be an until? Larry didn't say loop was replacing while. He said that the magic do {} while was going away to be replaced by loop. while and until (both as loops and modifiers) will still be around AFAIK. 1. Larry says loops will have ELSE blocks inside them. Did he say that? Or was it inferred from NEXT, LAST, etc. by others? No he didn't. Again, flaky memory on my part. What DAMIAN said was: Larry has been mulling over whether various types of loop should be allowed to take Celse blocks to accomplish this. So, you can see where my confusion came from. It's not clear if this was suggesting loop{else{}} or loop{}else{}, but either way, this was the origin of the discussion. 4. I point out that elsif isn't so bad, and perhaps there should be an array of other else options. And I say, why have several specific things when you can have 1 generalized thing that does the same job. (I'm not going to describe it beyond that. It's up to Larry+Damian to define the shape of the thing) Well then, I guess we should dump elsif from if too. After all, it could all be done with nested blocks of if/else If we're to keep if the same, and add an else to loops, I think the syntax should be unified. You would then see code like: unless $fh = $x.open() { die $0: Cannot open $x; } elswhile $fh.getline() - $_ { print; } else { die $0: There were no lines to read from $x!\n; } Which is as clean and elegant as it gets, IMHO. So, the answer to your question is: yes, I do propose that there should be an elsif, elsloop and elsfor. That's it. Three words, not an expansive list of ever-more-complex words. You're just weird. :) Thanks ;) Now, I agree that else for might make more sense, but it's very ugly on the grammar (given that we don't allow free statements like C does). Hey, perl 6 is supposed to be optimized for the programmer, not the perl parser ;-) I agree. This is why I think conditionals and loops should have roughly the same syntax. Introducing a major twist in the grammar just so that loops and conditionals can be different, seems to hurt both camps equally and benefit none.
Re: Loop controls
I still don't like the idea of Celsifs on loops. I already do an instant double take with Celse of Where's the if? (with visions of old Wendy's commercials dancing in my head). Me too. That's why the looping else should be spelled otherwise IMHO. If a loop produced a boolean value depending on if it iterated over some values, then you could say: for (data) { # do stuff } or die Didn't do anything\n; Then again, maybe that'd be too confusing for both a human the the parser. I recommend you consider for a moment, then /dev/null the idea. Jonathan Paton __ Do You Yahoo!? Everything you'll ever need on one web page from News and Sport to Email and Music Charts http://uk.my.yahoo.com
Re: Loop controls
Aaron Sherman wrote: Of course it brings other less wholesome things to mind like elsfor and elsloop and if ... elsfor and for ... elsif ... elsloop ... else, but why not? Because Perl 6 is already...err...over-endowed with keywords, few of which are as klunky as these would be. If we were to generalize to cascaded loops I'm pretty sure we'd have to consider else if, else while, else for etc. instead. But the aliased value, $_, is restricted to the scope of the Cwhile's block, it isn't going to be accessible in the block associated with the Celse (you would be getting some $_ from an outer scope). You're thinking of loops in a curious and convoluted way, Err. No she's not. Allison is right on the money. She's thinking of loops in the Perl 6 way (which is less curious and convoluted). Try this out: { loop-keyword [ conditional/declaration ] block { else-clauses ...} } The loop itself comprises an outer scope in which the conditionals or declarations exist. Then, each block comprises a sub-scope. In this way, there is no confusion, no special case, no violation of the rules. Except the rule that there are no implicit scopes (except file scope). It becomes reasonable now to have: for a - $b { stuff using $b } elsfor c - $d { more stuff using $b and $d } else { yet further stuff with access to $b and $d } Except that, as Allison subsequently correctly pointed out, the aliasing arrow doesn't work that way at all. Damian
Re: Loop controls
So, the answer to your question is: yes, I do propose that there should be an elsif, elsloop and elsfor. That's it. Three words, not an expansive list of ever-more-complex words. Oh! I have an idea! Why don't we make the lexer just realize a prefix els on any operator. Then you could do Cif .. {} elsexit. :P My point is that, IMO, this whole els thing is completely preposterous. I'm the kind of person that likes to keep down on keywords. And I never liked Perl5's Celsif anyway; I always preferred Celse if. I really don't understand what at all is appealing about Celsloop. I don't want this thread to turn into a mindless squabble. Perhaps people could look at the thing a different way altogether, not taking side 1 or 2, but rather 1+2i. Here's my synopsis of how everything's gone so far: We have the following syntaxes for elses on loops (for any kind, not just loop). loop ;; {} else {} loop ;; { else {} } loop ;; { ELSE {} } Or replace any of these with Cotherwise. Furthermore, we have a couple of different ways for loops to come after elses: elsloop ;; {} else loop ;; {} else { loop ;; {} } I don't think Cotherwisloop has been proposed :). If anyone has other ideas, or an insanely good reason why one of these is optimal, we're all ears. I think we all trust Larry to make the right decision, but he might not be God. New ideas are good. Luke
Re: Loop controls
On Mon, Apr 29, 2002 at 04:14:01PM -0400, Aaron Sherman wrote: Well then, I guess we should dump elsif from if too. After all, it could all be done with nested blocks of if/else But Celsif is different. You use it all the time. The frequency with which you'd need a loop that leads into another loop that leads into a conditional isn't worthy of special keywords for each combination. It's like coming up with a catchy word for that place on the corner of the sidewalk that dips down for wheel-chairs, bicycles and strollers (er, prams). It's not worth it. (Maybe there is such a word, but I don't remember it because I don't use it.) If we're to keep if the same, and add an else to loops, I think the syntax should be unified. There is a time for unification and a time for differentiation. Total unification would take us back to assembly, There can be only jumps. Everything is a balance. Allison
Re: Loop controls
Concerning the els(loop|for|while) controversy, I'd like to bring it back to the point that started it all: loop-else. There seems to be a fair amount of support for a loop-else contruct. Can we/Larry decide to accept loop-else, regardless of what other decisions need to be made? It would be a shame to see a really useful construct like that get tossed out because we're afraid we can't stop ourselves. I would rather see loop-else with no elsloop than lose the whole idea. -Miko
Re: Loop controls
On Mon, 2002-04-29 at 16:41, Luke Palmer wrote: So, the answer to your question is: yes, I do propose that there should be an elsif, elsloop and elsfor. That's it. Three words, not an expansive list of ever-more-complex words. Oh! I have an idea! Why don't we make the lexer just realize a prefix els on any operator. Then you could do Cif .. {} elsexit. :P That's just a bit more off-the-wall than adding for keywords (the three above, plus I've been corrected on the while thing). Let's not get too hyperbolic here; it doesn't help the discussion along much. My point is that, IMO, this whole els thing is completely preposterous. I'm the kind of person that likes to keep down on keywords. And I never liked Perl5's Celsif anyway; I always preferred Celse if. I really don't understand what at all is appealing about Celsloop. If you want if/else if, talk to Larry (I would not disagree, though old friends are hard to part with). I'm just saying that as long as if has the syntax it has, we should replicate that on loops. I don't want this thread to turn into a mindless squabble. Perhaps people could look at the thing a different way altogether, not taking side 1 or 2, but rather 1+2i. We've had a lot of good thought here, and I see this as anything but a mindless squabble. Here's my synopsis of how everything's gone so far: We have the following syntaxes for elses on loops (for any kind, not just loop). loop ;; {} else {} loop ;; { else {} } loop ;; { ELSE {} } See the thread that Damian started, which discusses these options. Furthermore, we have a couple of different ways for loops to come after elses: elsloop ;; {} else loop ;; {} else { loop ;; {} } Correct, and this has been pointed out previously in the thread. Thank you for collecting it. I think the reasoning for each, respectively is: 1. Consistent syntax with if/elsif/else 2. Cleaner 3. No new syntax required I agree with all three points. I have a feeling we're not going to get if/else if, but if we do I prefer the second. If we don't I prefer the first.
Re: Loop controls
Aaron Sherman wrote: Er, what?!? Who said we're dropping until? Did I miss something? Well, if there's no while (replaced by generic loop, per Apoc4) why would there be an until? As Aaron himself has discovered, neither Cwhile nor Cuntil is being dropped from Perl 6. Incidently, even Cdo {...} while ... is still allowed. We're just changing its semantics slightly (it no longer iterates once before the conditional check) so that it's consistent with the rest of Perl 6. Ok, once more for those in the cheap seats (no offense, it's just a lot of people seemed to have ignored the thread until now and jumped in without the context), this is how we got here: 1. Larry says loops will have ELSE blocks inside them. No, Allison said that. And she was wearing her Devil's Advocate hat at the time. So, the answer to your question is: yes, I do propose that there should be an elsif, elsloop and elsfor. That's it. Three words, not an expansive list of ever-more-complex words. and 'elswhile'. *Four* words: 'elsif', 'elsloop', 'elsfor', 'elswhile', and 'elsuntil'. *Five* words... *No-one* expects the Spanish Inquisition! ;-) Damian
Re: Loop controls
Aaron Sherman wrote: while $result.get_next() - $next { # do something with $next... ELSE { # do something otherwise with $next } } } Here's the code, expanded: Unfortunately, that code isn't even close to the Perl 6 semantics of Cwhile loops. Is there any reason to do it the other way? Yes. Good reasons. The most important of which is the notion that there are no magic lexical scopes. Damian