digitalmars.D - RFC: Behavior of continue in do/while loops.
- Downs (26/26) Sep 12 2007 -----BEGIN PGP SIGNED MESSAGE-----
- Steven Schveighoffer (18/33) Sep 12 2007 My view of the continue statement is that it means "I am done with this
- Downs (20/62) Sep 12 2007 -----BEGIN PGP SIGNED MESSAGE-----
- Steven Schveighoffer (19/33) Sep 12 2007 I appreciate that you have issues with the continue statement, but I thi...
- Regan Heath (36/65) Sep 12 2007 I tend not to use do/while in favour of while and for loops myself so I
- Downs (14/22) Sep 12 2007 -----BEGIN PGP SIGNED MESSAGE-----
- Regan Heath (14/24) Sep 12 2007 I don't agree, 'go back to the start of this loop' simply isn't what
- Downs (24/53) Sep 12 2007 -----BEGIN PGP SIGNED MESSAGE-----
- Regan Heath (4/22) Sep 13 2007 I still don't agree that it "_behaves_ the same, as seen from the
- 0ffh (8/8) Sep 12 2007 Hi, downs!
- Steven Schveighoffer (17/20) Sep 12 2007 BTW, usually the compiler re-arranges a while loop so that the condition...
- renoX (21/50) Sep 12 2007 Bah, a matter of opinion, I interpret 'continue' as 'continue to the
- Manfred Nowak (9/12) Sep 12 2007 No.
- Downs (25/42) Sep 12 2007 -----BEGIN PGP SIGNED MESSAGE-----
- BCS (5/12) Sep 12 2007 I think this will get you the same result
- Steven Schveighoffer (5/17) Sep 12 2007 I think it needs to be:
- BCS (2/26) Sep 12 2007 silly me. I used the current semantics, not what he was looking for.
- Manfred Nowak (3/10) Sep 12 2007 ... more entangled than I thought :-)
- Derek Parnell (25/32) Sep 12 2007 No.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I just came upon the interesting fact that using the "continue" statement in a do { } while() loop does not, in fact, continue with the next loop, but instead continues with the _condition_. I know this is the same behavior as in C, but as somebody who never encountered it before I can assure you, it's highly unintuitive. The confusion here stems largely from the way a do/while loop looks - the condition is found at the _end_ at the loop body, yet I expected continue to jump to the _beginning_. There is two questions I want to ask: First, if you were starting a new language, should the behavior of continue in that language match what I expected in this case? (theoretical case) And second, should the behavior be changed in the D programming language, even though it _might_ conceivably break code that relies on the current behavior? (practical case) Looking forward to your comments, --downs -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFG6AvvpEPJRr05fBERAnfQAJ0UapoxtHQCtIfTerkFe3iUnTHXtACfTFj4 ennSYblhmnx1yOzb6izeCfs= =kBA4 -----END PGP SIGNATURE-----
Sep 12 2007
"Downs" wroteI just came upon the interesting fact that using the "continue" statement in a do { } while() loop does not, in fact, continue with the next loop, but instead continues with the _condition_. I know this is the same behavior as in C, but as somebody who never encountered it before I can assure you, it's highly unintuitive. The confusion here stems largely from the way a do/while loop looks - the condition is found at the _end_ at the loop body, yet I expected continue to jump to the _beginning_. There is two questions I want to ask: First, if you were starting a new language, should the behavior of continue in that language match what I expected in this case? (theoretical case)My view of the continue statement is that it means "I am done with this iteration of the loop, skip to the next one." In that sense, I think the continue statement works correctly as it is implemented today. BTW, you could implement what you want by using an infinite loop and a break statement. i.e.: do { ... } while(condition) becomes: while(true) { ... if(condition) break; }And second, should the behavior be changed in the D programming language, even though it _might_ conceivably break code that relies on the current behavior? (practical case)Nope :) Alienating C/Java developers is not a good idea. -Steve
Sep 12 2007
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Steven Schveighoffer wrote:"Downs" wroteYeah, that's what I ended up doing.I just came upon the interesting fact that using the "continue" statement in a do { } while() loop does not, in fact, continue with the next loop, but instead continues with the _condition_. I know this is the same behavior as in C, but as somebody who never encountered it before I can assure you, it's highly unintuitive. The confusion here stems largely from the way a do/while loop looks - the condition is found at the _end_ at the loop body, yet I expected continue to jump to the _beginning_. There is two questions I want to ask: First, if you were starting a new language, should the behavior of continue in that language match what I expected in this case? (theoretical case)My view of the continue statement is that it means "I am done with this iteration of the loop, skip to the next one." In that sense, I think the continue statement works correctly as it is implemented today. BTW, you could implement what you want by using an infinite loop and a break statement. i.e.: do { ... } while(condition) becomes: while(true) { ... if(condition) break; }miller[] came up with two good alternatives over in #D 1) forbidding continue in do/while and replacing it with continue do/continue while, or 2) adding goto do/goto while statements. The first one has the advantage of making it totally impossible for a newcomer to trip on this, while the second one has the advantage of not breaking existing code. Whaddya think? --downs -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFG6BnJpEPJRr05fBERAsnFAJ4xcsAi5bkk5JRVa+lM/mv+kafurgCcCU0n /g7nchrjUCIBAW9+EpRgo/g= =TslT -----END PGP SIGNATURE-----And second, should the behavior be changed in the D programming language, even though it _might_ conceivably break code that relies on the current behavior? (practical case)Nope :) Alienating C/Java developers is not a good idea. -Steve
Sep 12 2007
"Downs" wroteSteven Schveighoffer wrote:I appreciate that you have issues with the continue statement, but I think they are very subtle, and very uncommon. That and the fact that precedence is to have continue re-evaluate the condition will likely result in the language not changing. I look at a do-while loop as a while loop that you want to execute at least once. The whole goal of it was to eliminate having to re-code the loop contents outside the loop so this would occur. What you want seems to me like a *restart* of the loop, not a *continuance*. I think making continue skip the condition is prone to more problems then it is worth (imagine someone switching a while loop to a do-while and then some kind of infinite loop occurs because there was a continue statement). I think adding syntax is not necessary since you can express your version of the loop easily with the current implementation. However, seeing as how I never use goto in my code, and there is precedence for using goto in other constructs (goto case, goto default), I have no problem with adding goto do (goto while is already handled by continue). But it's not up to me :) -SteveNope :) Alienating C/Java developers is not a good idea. -Stevemiller[] came up with two good alternatives over in #D 1) forbidding continue in do/while and replacing it with continue do/continue while, or 2) adding goto do/goto while statements. The first one has the advantage of making it totally impossible for a newcomer to trip on this, while the second one has the advantage of not breaking existing code. Whaddya think?
Sep 12 2007
Downs wrote:-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I just came upon the interesting fact that using the "continue" statement in a do { } while() loop does not, in fact, continue with the next loop, but instead continues with the _condition_. I know this is the same behavior as in C, but as somebody who never encountered it before I can assure you, it's highly unintuitive. The confusion here stems largely from the way a do/while loop looks - the condition is found at the _end_ at the loop body, yet I expected continue to jump to the _beginning_. There is two questions I want to ask: First, if you were starting a new language, should the behavior of continue in that language match what I expected in this case? (theoretical case) And second, should the behavior be changed in the D programming language, even though it _might_ conceivably break code that relies on the current behavior? (practical case) Looking forward to your comments, --downs -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFG6AvvpEPJRr05fBERAnfQAJ0UapoxtHQCtIfTerkFe3iUnTHXtACfTFj4 ennSYblhmnx1yOzb6izeCfs= =kBA4 -----END PGP SIGNATURE-----I tend not to use do/while in favour of while and for loops myself so I hadn't really bumped into this behaviour nor needed to imagine what it might do. But, now that I know what it does, thinking about it, I reckon it's the correct (and intuitive - matter of opinion) thing for it to do and I don't think it should change. I suspect whether it is intuitive or not depends on how you think of 'continue', for example: However, if you think of 'continue' as meaning 'go to the next iteration' then you would expect it to do whatever it would have done at the end of this iteration, before the next one. If you think of 'continue' as meaning 'go back to the start of the(this?) loop' then you wouldn't expect the condition to be evaluated. I believe 'go to the next iteration' is the correct interpretation of 'continue'. In do/while, while and for to get from one iteration to the next you have to pass the condition. This is the contract/guarantee that the loop provides. Making the change you suggest will remove this guarantee, making it possible to go from iteration n to iteration n+1 without checking the condition. Despite the fact that the first iteration of do/while should be safe without the guarantee the 2nd-nth ones might not be, eg. if (*input != 0) { char *p = input; do { ..etc.. p++; ..etc.. continue; ..etc.. } while(*p != '\0'); } Regan
Sep 12 2007
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Regan Heath wroteI suspect whether it is intuitive or not depends on how you think of 'continue', for example:However, if you think of 'continue' as meaning 'go to the next iteration' then you would expect it to do whatever it would have done at the end of this iteration, before the next one.If you think of 'continue' as meaning 'go back to the start of the(this?) loop' then you wouldn't expect the condition to be evaluated.The problem here is that for every case *but* a do/while loop, the two perspectives behave exactly the same. See my follow-up to the other post for a way to prevent this conflict.Regan- --downs -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFG6Bp5pEPJRr05fBERAuSBAKCLsmjUOiW/+xW+18EMOIs1v5bfkQCfTuvN r1q+L+5LTegmDMgs/V0/VlA= =JjXp -----END PGP SIGNATURE-----
Sep 12 2007
Downs wrote:I don't agree, 'go back to the start of this loop' simply isn't what 'continue' does, in _any_ case. In all cases when you execute continue you move from iteration n to n+1. Moving from one iteration to the next _always_ involves checking the loop condition. The only difference between do/while and the other loops is that the 1st iteration is 'unprotected' by the guarantee of the loop condition. That's it. Expecting continue to 'go back to the start of this loop' is simply incorrect thinking. If you really want to 'go back to the start of this loop' you have to use goto. I don't really see the point in either of the solutions you have in the other thread, but then "it's not up to me". ReganHowever, if you think of 'continue' as meaning 'go to the next iteration' then you would expect it to do whatever it would have done at the end of this iteration, before the next one.If you think of 'continue' as meaning 'go back to the start of the(this?) loop' then you wouldn't expect the condition to be evaluated.The problem here is that for every case *but* a do/while loop, the two perspectives behave exactly the same. See my follow-up to the other post for a way to prevent this conflict.
Sep 12 2007
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Regan Heath wrote:Downs wrote:I know that's not what it _does_, but that wasn't my point. My point was that it _behaves_ the same, as seen from the *outside*, leading to misunderstandings.I don't agree, 'go back to the start of this loop' simply isn't what 'continue' does, in _any_ case. In all cases when you execute continue you move from iteration n to n+1. Moving from one iteration to the next _always_ involves checking the loop condition.However, if you think of 'continue' as meaning 'go to the next iteration' then you would expect it to do whatever it would have done at the end of this iteration, before the next one.If you think of 'continue' as meaning 'go back to the start of the(this?) loop' then you wouldn't expect the condition to be evaluated.The problem here is that for every case *but* a do/while loop, the two perspectives behave exactly the same. See my follow-up to the other post for a way to prevent this conflict.The only difference between do/while and the other loops is that the 1st iteration is 'unprotected' by the guarantee of the loop condition. That's it. Expecting continue to 'go back to the start of this loop' is simply incorrect thinking. If you really want to 'go back to the start of this loop' you have to use goto.I know that now. The problem is that because the two perspectives are so similar, *despite only one being technically correct*, it's easy to mistake the other one for the correct one if you learned coding by trial-and-error (as I did).I don't really see the point in either of the solutions you have in the other thread, but then "it's not up to me".The point is to prevent such misunderstandings from occuring again by forcing the programmer to explicitly state what he wants, _independent of his perspective_. So even if he has the wrong idea of how continue actually works (as I did), he'll still be able to get the behavior he expected.Regan--downs -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFG6DSkpEPJRr05fBERAuF9AJ4xNOlwp2b6EkLEH1QFHdZ7Fs3oogCeLLog zzpqAwdpoZujDL6HgoOh+Wo= =wGHk -----END PGP SIGNATURE-----
Sep 12 2007
Downs wrote:Regan Heath wrote:I still don't agree that it "_behaves_ the same, as seen from the *outside*" but I wont labour the point. ReganDowns wrote:I know that's not what it _does_, but that wasn't my point. My point was that it _behaves_ the same, as seen from the *outside*, leading to misunderstandings.I don't agree, 'go back to the start of this loop' simply isn't what 'continue' does, in _any_ case. In all cases when you execute continue you move from iteration n to n+1. Moving from one iteration to the next _always_ involves checking the loop condition.However, if you think of 'continue' as meaning 'go to the next iteration' then you would expect it to do whatever it would have done at the end of this iteration, before the next one. If you think of 'continue' as meaning 'go back to the start of the(this?) loop' then you wouldn't expect the condition to be evaluated.The problem here is that for every case *but* a do/while loop, the two perspectives behave exactly the same. See my follow-up to the other post for a way to prevent this conflict.
Sep 13 2007
Hi, downs! Hmmm, I don't think the behaviour as-is is counterintuitive, but that's a matter of individual preconditioning, I gather. Also, the instances of me using the do...while construct are few and far between, because I consider it looks rather ugly and seldom find myself in a situation where I'd be forced to use it (read: where it'd make the code better :-). Regards, Frank
Sep 12 2007
"Downs" wroteThe confusion here stems largely from the way a do/while loop looks - the condition is found at the _end_ at the loop body, yet I expected continue to jump to the _beginning_.BTW, usually the compiler re-arranges a while loop so that the condition is at the end also. Looks something like this: while(condition) { ... } becomes JMP loop loopstart: ... loop: TST condition ; sets zero flag if condition is true JNZ loopstart Actually, I have no idea how to code in assembly, so my code is probably worthless, but you get the idea :) -Steve
Sep 12 2007
Downs a écrit :-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I just came upon the interesting fact that using the "continue" statement in a do { } while() loop does not, in fact, continue with the next loop, but instead continues with the _condition_.Yes, that's what I would expect.I know this is the same behavior as in C, but as somebody who never encountered it before I can assure you, it's highly unintuitive.Bah, a matter of opinion, I interpret 'continue' as 'continue to the end', why would 'continue to the beginning' more intuitive?The confusion here stems largely from the way a do/while loop looks - the condition is found at the _end_ at the loop body, yet I expected continue to jump to the _beginning_.But even in a for loop, continue doesn't really continue to the beginning of the loop, it continue to the 'termination test'.There is two questions I want to ask: First, if you were starting a new language, should the behavior of continue in that language match what I expected in this case? (theoretical case)No, current continue behaviour is consistent for while/for/do .. while which is good. Maybe a different keyword could be more intuitive, but I can't find any (skip has the same issue, goto_end is not clear if it's break or continue, etc) unless you want to start using keyword like continue_to_end_of_iteration..And second, should the behavior be changed in the D programming language, even though it _might_ conceivably break code that relies on the current behavior? (practical case)No: 1) the continue behaviour is coherent. 2) it's consistent with C's behaviour. There are many thing that I dislike in C (stupid variable declaration syntax, use of && for shortcut-and instead of & even though shortcut-and are much more used than binary-and, use 0 to start octal instead of 0o ,etc) but continue isn't one of these (except that it should take a 'loop label' as an optional argument as D's continue does). renoXLooking forward to your comments, --downs -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFG6AvvpEPJRr05fBERAnfQAJ0UapoxtHQCtIfTerkFe3iUnTHXtACfTFj4 ennSYblhmnx1yOzb6izeCfs= =kBA4 -----END PGP SIGNATURE-----
Sep 12 2007
Downs wroteFirst, if you were starting a new language, should the behavior of continue in that language match what I expected in this case? (theoretical case)No. According to your introduction you might have entangled yourself by trying to optimize away a loop nested in another loop: do{ do{ }while( ); }while( ); -manfred
Sep 12 2007
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Manfred Nowak wrote:Downs wroteActually, I was writing HTTP a downloader and trying to make it embed special-case logic for 1.1 chunks in a 1.0 loop along the lines of do { receive; if (isChunked) { if (chunkedDownloading) continue; break; } } while (notReceivedEnough) so I expected the continue to restart the loop, but it executed the condition (which naturally failed abysmally, because I wasn't doing a normal download :) Doesn't matter, it works now. --downs -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFG6E+JpEPJRr05fBERAp4bAJ9W/K15qgbpPg+P301+rBNeKC/PcACgkVgj 6N0xl0ARvyd5pqcc8kBWKlc= =YDS2 -----END PGP SIGNATURE-----First, if you were starting a new language, should the behavior of continue in that language match what I expected in this case? (theoretical case)No. According to your introduction you might have entangled yourself by trying to optimize away a loop nested in another loop: do{ do{ }while( ); }while( ); -manfred
Sep 12 2007
Downs wrote:do { receive; if (isChunked) { if (chunkedDownloading) continue; break; } } while (notReceivedEnough)I think this will get you the same result do { receive; } while (isChunked && chunkedDownloading && notReceivedEnough)
Sep 12 2007
"BCS" <BCS pathlink.com> wrote in message news:fc9kjm$28pv$1 digitalmars.com...Downs wrote:I think it needs to be: while(isChunked && chunkedDownloading || !isChunked && notReceivedEnough) -Stevedo { receive; if (isChunked) { if (chunkedDownloading) continue; break; } } while (notReceivedEnough)I think this will get you the same result do { receive; } while (isChunked && chunkedDownloading && notReceivedEnough)
Sep 12 2007
Reply to Steven,"BCS" <BCS pathlink.com> wrote in message news:fc9kjm$28pv$1 digitalmars.com...silly me. I used the current semantics, not what he was looking for.Downs wrote:I think it needs to be: while(isChunked && chunkedDownloading || !isChunked && notReceivedEnough) -Stevedo { receive; if (isChunked) { if (chunkedDownloading) continue; break; } } while (notReceivedEnough)I think this will get you the same result do { receive; } while (isChunked && chunkedDownloading && notReceivedEnough)
Sep 12 2007
Downs wrotedo { receive; if (isChunked) { if (chunkedDownloading) continue; break; } } while (notReceivedEnough)... more entangled than I thought :-) -manfred
Sep 12 2007
On Wed, 12 Sep 2007 17:55:27 +0200, Downs wrote:There is two questions I want to ask: First, if you were starting a new language, should the behavior of continue in that language match what I expected in this case? (theoretical case)Yes.And second, should the behavior be changed in the D programming language, even though it _might_ conceivably break code that relies on the current behavior? (practical case)No. However, if the introduction of scoped-labels is made, this becomes a simple goto issue. do { top: . . . if (whatever) goto top; . . . } while( some_condition); do { top: . . . if (anothertest) goto top; . . . } while( some_other_condition); At the moment, the scope of labels is too large and you have to invent new label identifiers for each block scope. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Sep 12 2007