digitalmars.D - OT: for (;;) {} vs while (true) {}
- Dennis Ritchie (7/7) Nov 24 2016 Hi all,
- LiNbO3 (6/13) Nov 24 2016 As you can see [1] the `while (true)` is lowered into `for
- Dennis Ritchie (7/11) Nov 24 2016 OK, thanks.
- Andrei Alexandrescu (3/16) Nov 24 2016 I wouldn't ding anyone in a code review for using one vs the other. --
- Claude (8/21) Nov 25 2016 Between "for(;;)", "while(true)" and "do while(true)", I would
- Timon Gehr (4/10) Nov 25 2016 You can just as easily edit the while condition. I use it because
- Jonathan M Davis via Digitalmars-d (8/15) Nov 25 2016 Probably the complete lack of a condition to test in for(;;). I confess ...
- Dennis Ritchie (6/14) Nov 25 2016 IMO, it is very convenient for system programming guru. It is
- Andrei Alexandrescu (15/27) Nov 25 2016 I like that function. If I were to review it now, I'd approve with these...
- Dennis Ritchie (6/9) Nov 25 2016 The problem is not the users, and the places where you will use
- Jonathan M Davis via Digitalmars-d (14/20) Nov 25 2016 I would point out that technically, that breaks the range API. isInputRa...
- Andrei Alexandrescu (2/3) Nov 25 2016 We need to change the range API then. -- Andrei
- Adam D. Ruppe (9/10) Nov 25 2016 That's absurd, popFront is in no way semantically a property, so
- Andrei Alexandrescu (2/5) Nov 25 2016 Agreed. -- Andrei
- Jonathan M Davis via Digitalmars-d (22/27) Nov 25 2016 That's fine, but it doesn't help any when the callable can't be used wit...
- Meta (4/15) Dec 01 2016 This causes a world of pain when you want to pass functions
- Jonathan M Davis via Digitalmars-d (10/29) Dec 01 2016 I think that having optional parens in D was a mistake, and your situati...
- Jonathan M Davis via Digitalmars-d (9/12) Nov 25 2016 We can certainly do that. I'm just pointing out that as it stands, it's
- Steven Schveighoffer (8/23) Nov 25 2016 This is a misunderstanding. The missing parens is for *usage* of the
- Jonathan M Davis via Digitalmars-d (42/69) Nov 25 2016 It's not a misunderstanding.
- Andrei Alexandrescu (2/14) Nov 25 2016 Jonathan, could you please make a PR to remove the parens. Thanks. -- An...
- Jonathan M Davis via Digitalmars-d (5/6) Nov 25 2016 Done.
- Steven Schveighoffer (9/40) Nov 25 2016 It's perfectly legal to make a popFront that destroys your entire
- Kagamin (29/33) Nov 25 2016 Seems like not that many.
- Claude (13/28) Nov 25 2016 In the general sense:
- Claude (11/11) Nov 25 2016 Sorry, I sent my post before finishing it, so...
- Kagamin (8/11) Nov 25 2016 Unconditional loop can be implemented in 3 possible ways :)
- Timon Gehr (2/11) Nov 25 2016 Grab a dictionary.
- H. S. Teoh via Digitalmars-d (22/36) Nov 25 2016 Sure it does. A conditionless loop is exactly what an infinite loop is.
- Dennis Ritchie (20/20) Nov 25 2016 I don't mean an infinite loop for (;;), and violation of the
- Nick Sabalausky (4/15) Dec 01 2016 Personal preference. Nothing more. Programmers have far better things to...
- H. S. Teoh via Digitalmars-d (8/16) Dec 01 2016 Far better things? You mean, like having endless discussions about a
- unDEFER (2/2) Nov 24 2016 Why you consider only 2 options?
- rikki cattermole (3/5) Nov 25 2016 The condition only executes after a single iteration.
- Stefan Koch (4/9) Nov 25 2016 For an the usecase infinite-loop the code has the same effect.
Hi all, In the source code, written in D, is often used in the design of the `for (;;) { ... }` Maybe someone has specific examples of translation of code in asm, where `while (true) { ... }` or `for (;;) { ... }` affect the performance or cross-platform programs. It would be interesting to see samples.
Nov 24 2016
On Thursday, 24 November 2016 at 21:57:15 UTC, Dennis Ritchie wrote:Hi all, In the source code, written in D, is often used in the design of the `for (;;) { ... }` Maybe someone has specific examples of translation of code in asm, where `while (true) { ... }` or `for (;;) { ... }` affect the performance or cross-platform programs. It would be interesting to see samples.As you can see [1] the `while (true)` is lowered into `for (;true;)` so it's all about what construct pleases you the most. [1] https://github.com/dlang/dmd/blob/cd451ceae40d04f7371e46df1c955fd914f3085f/src/statementsem.d#L357
Nov 24 2016
On Thursday, 24 November 2016 at 22:04:00 UTC, LiNbO3 wrote:As you can see [1] the `while (true)` is lowered into `for (;true;)` so it's all about what construct pleases you the most. [1] https://github.com/dlang/dmd/blob/cd451ceae40d04f7371e46df1c955fd914f3085f/src/statementsem.d#L357OK, thanks. The next question is: What principles guided when choosing between `for (;;) { ... }` and `while (true) { ... }` ? For example, there are two options: https://github.com/dlang/phobos/blob/master/std/algorithm/sorting.d
Nov 24 2016
On 11/24/2016 05:09 PM, Dennis Ritchie wrote:On Thursday, 24 November 2016 at 22:04:00 UTC, LiNbO3 wrote:I wouldn't ding anyone in a code review for using one vs the other. -- AndreiAs you can see [1] the `while (true)` is lowered into `for (;true;)` so it's all about what construct pleases you the most. [1] https://github.com/dlang/dmd/blob/cd451ceae40d04f7371e46df1c955fd914f3085f/src/statementsem.d#L357OK, thanks. The next question is: What principles guided when choosing between `for (;;) { ... }` and `while (true) { ... }` ? For example, there are two options: https://github.com/dlang/phobos/blob/master/std/algorithm/sorting.d
Nov 24 2016
On Thursday, 24 November 2016 at 22:09:22 UTC, Dennis Ritchie wrote:On Thursday, 24 November 2016 at 22:04:00 UTC, LiNbO3 wrote:Between "for(;;)", "while(true)" and "do while(true)", I would use the "while (true) { }" for pure readability and semantic reasons. I reckon "for(;;)" form is used for debug reasons (so you can easily insert conditions to transform an infinite loop into a finite one).As you can see [1] the `while (true)` is lowered into `for (;true;)` so it's all about what construct pleases you the most. [1] https://github.com/dlang/dmd/blob/cd451ceae40d04f7371e46df1c955fd914f3085f/src/statementsem.d#L357OK, thanks. The next question is: What principles guided when choosing between `for (;;) { ... }` and `while (true) { ... }` ? For example, there are two options: https://github.com/dlang/phobos/blob/master/std/algorithm/sorting.d
Nov 25 2016
On 25.11.2016 11:33, Claude wrote:... Between "for(;;)", "while(true)" and "do while(true)", I would use the "while (true) { }" for pure readability and semantic reasons. ...What semantic reasons?I reckon "for(;;)" form is used for debug reasons (so you can easily insert conditions to transform an infinite loop into a finite one).You can just as easily edit the while condition. I use it because "unconditional loop" is less silly than "loop until true is false".
Nov 25 2016
On Friday, November 25, 2016 12:10:44 Timon Gehr via Digitalmars-d wrote:On 25.11.2016 11:33, Claude wrote:Probably the complete lack of a condition to test in for(;;). I confess that I was shocked when I found out that it was legal to have a for loop without a condition. That seems like doing while() or if(), which makes no sense. So, I never use for(;;) and wish that it didn't exist, but it does, and some folks use it. So, I have to live with the possiblity of dealing with it when dealing with code written by other people. But I won't ever use it. - Jonathan M Davis... Between "for(;;)", "while(true)" and "do while(true)", I would use the "while (true) { }" for pure readability and semantic reasons. ...What semantic reasons?
Nov 25 2016
On Friday, 25 November 2016 at 11:20:24 UTC, Jonathan M Davis wrote:Probably the complete lack of a condition to test in for(;;). I confess that I was shocked when I found out that it was legal to have a for loop without a condition. That seems like doing while() or if(), which makes no sense. So, I never use for(;;) and wish that it didn't exist, but it does, and some folks use it. So, I have to live with the possiblity of dealing with it when dealing with code written by other people. But I won't ever use it.IMO, it is very convenient for system programming guru. It is believed that it came from the K&R. For example, this option is definitely very convenient to use: https://github.com/dlang/phobos/blob/master/std/algorithm/comparison.d#L591
Nov 25 2016
On 11/25/2016 07:53 AM, Dennis Ritchie wrote:On Friday, 25 November 2016 at 11:20:24 UTC, Jonathan M Davis wrote:I like that function. If I were to review it now, I'd approve with these nits: * drop the parens for popFront * s/-cast(int)!r2.empty/-int(!r2.empty)/ * Merge with the cmp implementation for strings and simplify the constraint from if (isInputRange!R1 && isInputRange!R2 && !(isSomeString!R1 && isSomeString!R2)) to if (isInputRange!R1 && isInputRange!R2) i.e. it's not relevant to users that the string version has a distinct implementation. In fact I suggest someone implements this. AndreiProbably the complete lack of a condition to test in for(;;). I confess that I was shocked when I found out that it was legal to have a for loop without a condition. That seems like doing while() or if(), which makes no sense. So, I never use for(;;) and wish that it didn't exist, but it does, and some folks use it. So, I have to live with the possiblity of dealing with it when dealing with code written by other people. But I won't ever use it.IMO, it is very convenient for system programming guru. It is believed that it came from the K&R. For example, this option is definitely very convenient to use: https://github.com/dlang/phobos/blob/master/std/algorithm/comparison.d#L591
Nov 25 2016
On Friday, 25 November 2016 at 12:59:07 UTC, Andrei Alexandrescu wrote:i.e. it's not relevant to users that the string version has a distinct implementation. In fact I suggest someone implements this.The problem is not the users, and the places where you will use your program. Because this code is easy to make a mistake that can lead to failure in the automated system. Unfortunately, writing such code is not safe.
Nov 25 2016
On Friday, November 25, 2016 07:59:07 Andrei Alexandrescu via Digitalmars-d wrote:On 11/25/2016 07:53 AM, Dennis Ritchie wrote:I would point out that technically, that breaks the range API. isInputRange requires that popFront be callable with parens, but it does not require that it be callable without parens. So, someone could define popFront as a public member variable with an overloaded opCall. That would not compile if it were used with code that called popFront without parens even though it would compile with isInputRange. Now, realistically, no one is going to do that, so it probably doesn't matter. But it seems to me that in general, when dealing with a trait like isInputRange which tests that a particular syntax is used, it's just safer to use that syntax rather than using parens where it doesn't or not using parens where it does. - Jonathan M Davishttps://github.com/dlang/phobos/blob/master/std/algorithm/comparison.d#L 591I like that function. If I were to review it now, I'd approve with these nits: * drop the parens for popFront
Nov 25 2016
On 11/25/16 8:24 AM, Jonathan M Davis via Digitalmars-d wrote:I would point out that technically, that breaks the range API.We need to change the range API then. -- Andrei
Nov 25 2016
On Friday, 25 November 2016 at 15:03:26 UTC, Andrei Alexandrescu wrote:We need to change the range API then. -- AndreiThat's absurd, popFront is in no way semantically a property, so it should not get property. It has been so many years of this being poorly defined. Let's just close the book and officially put the status quo on optional parenthesis in stone: they are optional on zero-argument calls, regardless of property, and that isn't going to change. Then this popFront question becomes moot.
Nov 25 2016
On 11/25/16 10:29 AM, Adam D. Ruppe wrote:Let's just close the book and officially put the status quo on optional parenthesis in stone: they are optional on zero-argument calls, regardless of property, and that isn't going to change.Agreed. -- Andrei
Nov 25 2016
On Friday, November 25, 2016 11:01:56 Andrei Alexandrescu via Digitalmars-d wrote:On 11/25/16 10:29 AM, Adam D. Ruppe wrote:That's fine, but it doesn't help any when the callable can't be used with optional parens - which is the case with a type overloading opCall as well as function pointers and delegates. And the real problem here isn't whether someone chooses to call a function with parens or not in some chunk of their code. The problem is whether _generic_ code does it. If you're calling something with parens in generic code, then you need to be able to rely on it working with parens regardless of the types of the function arguments. And if you're calling it without parens, then you need to be able to rely on it working _without_ parens regardless of the types of the function arguments. Stuff like empty, save, and length in the range API all of the same problem as popFront and popBack except in reverse. In their case, they need to be called without parens, or the code won't work with some ranges (the most obvious case being for empty being infinite ranges, and the most obvious case for length being dynamic arrays). So, restricting popFront and popBack to being functions so that they can always be called without parens is fine, but it's still the case that you can't be completely lax with where you do or don't use parens in generic code. - Jonathan M DavisLet's just close the book and officially put the status quo on optional parenthesis in stone: they are optional on zero-argument calls, regardless of property, and that isn't going to change.Agreed. -- Andrei
Nov 25 2016
On Friday, 25 November 2016 at 15:29:31 UTC, Adam D. Ruppe wrote:On Friday, 25 November 2016 at 15:03:26 UTC, Andrei Alexandrescu wrote:This causes a world of pain when you want to pass functions around. Nothing gets my blood pressure up like the following code: https://forum.dlang.org/post/piktfrtpltmjvjmedspr forum.dlang.orgWe need to change the range API then. -- AndreiThat's absurd, popFront is in no way semantically a property, so it should not get property. It has been so many years of this being poorly defined. Let's just close the book and officially put the status quo on optional parenthesis in stone: they are optional on zero-argument calls, regardless of property, and that isn't going to change. Then this popFront question becomes moot.
Dec 01 2016
On Thursday, December 01, 2016 19:25:27 Meta via Digitalmars-d wrote:On Friday, 25 November 2016 at 15:29:31 UTC, Adam D. Ruppe wrote:I think that having optional parens in D was a mistake, and your situation there is an example of why it can be a big problem (the problems caused by being lax with syntax in generic code is another). However, the shipped has long since sailed on that one. It's too popular and too widely used to change at this point. And while I completely agree that allowing optional parens causes problems, it's also true that a lot of code is able to use it without difficulties, and many folks like it, particularly when they have to use parens for template arguments in UFCS call chains. - Jonathan M DavisOn Friday, 25 November 2016 at 15:03:26 UTC, Andrei Alexandrescu wrote:This causes a world of pain when you want to pass functions around. Nothing gets my blood pressure up like the following code: https://forum.dlang.org/post/piktfrtpltmjvjmedspr forum.dlang.orgWe need to change the range API then. -- AndreiThat's absurd, popFront is in no way semantically a property, so it should not get property. It has been so many years of this being poorly defined. Let's just close the book and officially put the status quo on optional parenthesis in stone: they are optional on zero-argument calls, regardless of property, and that isn't going to change. Then this popFront question becomes moot.
Dec 01 2016
On Friday, November 25, 2016 10:03:26 Andrei Alexandrescu via Digitalmars-d wrote:On 11/25/16 8:24 AM, Jonathan M Davis via Digitalmars-d wrote:We can certainly do that. I'm just pointing out that as it stands, it's legal to declare popFront to be a callable that doesn't work with optional parens, and as long as that's true, calling popFront without parens means that the code won't work with perfectly legitimate ranges. So, unless/until isInputRange is changed, I'd say that calling popFront without parens is a bad idea. - Jonathan M DavisI would point out that technically, that breaks the range API.We need to change the range API then. -- Andrei
Nov 25 2016
On 11/25/16 8:24 AM, Jonathan M Davis via Digitalmars-d wrote:On Friday, November 25, 2016 07:59:07 Andrei Alexandrescu via Digitalmars-d wrote:This is a misunderstanding. The missing parens is for *usage* of the range, not *definition* of the range. It won't affect isInputRange at all. This case you have of defining a popFront member variable with opCall -- don't do that, it will break things (I'm sure there are already many places where popFront is called without parens). I don't think that's a case that we need worry about. -Steve.On 11/25/2016 07:53 AM, Dennis Ritchie wrote:I would point out that technically, that breaks the range API. isInputRange requires that popFront be callable with parens, but it does not require that it be callable without parens. So, someone could define popFront as a public member variable with an overloaded opCall. That would not compile if it were used with code that called popFront without parens even though it would compile with isInputRange.https://github.com/dlang/phobos/blob/master/std/algorithm/comparison.d#L 591I like that function. If I were to review it now, I'd approve with these nits: * drop the parens for popFront
Nov 25 2016
On Friday, November 25, 2016 10:46:15 Steven Schveighoffer via Digitalmars-d wrote:On 11/25/16 8:24 AM, Jonathan M Davis via Digitalmars-d wrote:It's not a misunderstanding. template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); } calls popFront with parens. That means that it's perfectly legal per isInputRange to define popFront such that it's a callable that does _not_ work with optional parens. So, if it were a member variable that defined opCall or was a delegate, then to use it, the parens are required. That means that I could define a range that passes isInputRange but does not work with code that called popFront without parens. As isInputRange is currently defined, it's perfectly legal.On Friday, November 25, 2016 07:59:07 Andrei Alexandrescu via Digitalmars-d> wrote:This is a misunderstanding. The missing parens is for *usage* of the range, not *definition* of the range. It won't affect isInputRange at all.On 11/25/2016 07:53 AM, Dennis Ritchie wrote:I would point out that technically, that breaks the range API. isInputRange requires that popFront be callable with parens, but it does not require that it be callable without parens. So, someone could define popFront as a public member variable with an overloaded opCall. That would not compile if it were used with code that called popFront without parens even though it would compile with isInputRange.https://github.com/dlang/phobos/blob/master/std/algorithm/comparison.d #L 591I like that function. If I were to review it now, I'd approve with these nits: * drop the parens for popFrontThis case you have of defining a popFront member variable with opCall -- don't do that, it will break things (I'm sure there are already many places where popFront is called without parens). I don't think that's a case that we need worry about.It's a case that's currently legal. It's just not one that's particularly likely. We can certainly change isInputRange to make such a case illegal. But as it stands, someone could have defined such a range, and it would work with a _lot_ range-based code, because it's very common to call popFront with parens, and if such a range were being used with a function in Phobos, and that function were changed to call popFront without parens, it would break code. So, if we want to change the definition of isInputRange to get rid of this problem, fine. I'm just pointing out that as isInputRange is currently defined, calling popFront without parens would result in that code not working with ranges that are perfectly legal per isInputRange and could be perfectly legitimate ranges in all aspects of how they function. And calling empty _with_ parens even though it would be legal in most cases right now would have the exact same problem except in reverse. Everything wasn't a callable wouldn't work - including stuff like empty on infinite ranges. D allows us to be lax with syntax to some extent, but we need to be careful with how we deal with that in generic code, or we're going to end up with stuff that should work but doesn't just because parens happened to have been used or not in a particular piece of code. - Jonathan M Davis
Nov 25 2016
On 11/25/2016 11:47 AM, Jonathan M Davis via Digitalmars-d wrote:template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); } calls popFront with parens.Jonathan, could you please make a PR to remove the parens. Thanks. -- Andrei
Nov 25 2016
On Friday, November 25, 2016 11:51:24 Andrei Alexandrescu via Digitalmars-d wrote:Jonathan, could you please make a PR to remove the parens. Thanks.Done. https://github.com/dlang/phobos/pull/4925 - Jonathan M Davis
Nov 25 2016
On 11/25/16 11:47 AM, Jonathan M Davis via Digitalmars-d wrote:On Friday, November 25, 2016 10:46:15 Steven Schveighoffer via Digitalmars-d wrote:On 11/25/16 8:24 AM, Jonathan M Davis via Digitalmars-d wrote:It's perfectly legal to make a popFront that destroys your entire program. Or that doesn't actually pop the front (see old generate() function). So what? I can't see the point of going out of your way to make a popFront member that supports opCall, when you can use a function. Note: there are cases out there where popFront is called without parentheses. It has never broken any code. This should be a hint that what you are concerned about doesn't happen in practice. -SteveIt's not a misunderstanding. template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); } calls popFront with parens. That means that it's perfectly legal per isInputRange to define popFront such that it's a callable that does _not_ work with optional parens. So, if it were a member variable that defined opCall or was a delegate, then to use it, the parens are required. That means that I could define a range that passes isInputRange but does not work with code that called popFront without parens. As isInputRange is currently defined, it's perfectly legal.I would point out that technically, that breaks the range API. isInputRange requires that popFront be callable with parens, but it does not require that it be callable without parens. So, someone could define popFront as a public member variable with an overloaded opCall. That would not compile if it were used with code that called popFront without parens even though it would compile with isInputRange.This is a misunderstanding. The missing parens is for *usage* of the range, not *definition* of the range. It won't affect isInputRange at all.
Nov 25 2016
On Friday, 25 November 2016 at 15:46:15 UTC, Steven Schveighoffer wrote:This case you have of defining a popFront member variable with opCall -- don't do that, it will break things (I'm sure there are already many places where popFront is called without parens). I don't think that's a case that we need worry about.Seems like not that many. grep -r "popFront;" * algorithm/comparison.d: r2.popFront; algorithm/comparison.d: r1.popFront; algorithm/comparison.d: r1.popFront; algorithm/comparison.d: r2.popFront; algorithm/mutation.d: void popFront() { data.popFront; } experimental/allocator/typed.d: front, popFront; experimental/ndslice/selection.d: val.popFront; experimental/ndslice/selection.d: elems2.popFront; experimental/ndslice/selection.d: elems2.popFront; experimental/ndslice/selection.d: elems.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: value.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: value.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: slice.popFront; range/package.d: return condition ? r1.popFront : r2.popFront; The last one is strange.
Nov 25 2016
On Friday, 25 November 2016 at 11:10:44 UTC, Timon Gehr wrote:On 25.11.2016 11:33, Claude wrote:In the general sense: - While true (is always true), I loop. Is more meaningful and conceptually easy then the empty for statement : - For "empty initialization statement" until "I don't know (so forever by default)" and "not iterating", I loop.... Between "for(;;)", "while(true)" and "do while(true)", I would use the "while (true) { }" for pure readability and semantic reasons. ...What semantic reasons?I was just trying to explain why one would use for(;;) instead of while(true), you've got only one line to edit. It's in same vein as using: if (cond) { }I reckon "for(;;)" form is used for debug reasons (so you can easily insert conditions to transform an infinite loop into a finite one).You can just as easily edit the while condition. I use it because "unconditional loop" is less silly than "loop until true is false".
Nov 25 2016
Sorry, I sent my post before finishing it, so... It's in same vein as using: if (cond) { singleStatement; } instead of: if (cond) singleStatement; Because, you can more easily insert statements within the block (without having to navigate to different to insert the brackets).
Nov 25 2016
On Friday, 25 November 2016 at 11:10:44 UTC, Timon Gehr wrote:You can just as easily edit the while condition. I use it because "unconditional loop" is less silly than "loop until true is false".Unconditional loop can be implemented in 3 possible ways :) 1. skip it entirely: since there's no condition to check, can't decide if should enter at all 2. run once: since there's no condition to check, can't decide if should repeat - becomes just an unconditional block statement 3. infinite loop as if the condition is always true - until it's false
Nov 25 2016
On 25.11.2016 17:38, Kagamin wrote:On Friday, 25 November 2016 at 11:10:44 UTC, Timon Gehr wrote:Grab a dictionary.You can just as easily edit the while condition. I use it because "unconditional loop" is less silly than "loop until true is false".Unconditional loop can be implemented in 3 possible ways :) 1. skip it entirely: since there's no condition to check, can't decide if should enter at all 2. run once: since there's no condition to check, can't decide if should repeat - becomes just an unconditional block statement 3. infinite loop as if the condition is always true - until it's false
Nov 25 2016
On Fri, Nov 25, 2016 at 03:20:24AM -0800, Jonathan M Davis via Digitalmars-d wrote:On Friday, November 25, 2016 12:10:44 Timon Gehr via Digitalmars-d wrote:Sure it does. A conditionless loop is exactly what an infinite loop is. A while-loop, by definition, has a condition (loop *while* something is true, stop looping when it's no longer true), and an if-statement by definition is conditional. Neither match the nature of an infinite loop, which is infinite because it has no exit condition. Well, OK, a loop can also be infinite if the exit condition just happens to be always true, but I feel that is more deceptive than a conditionless loop when it's deliberately written, since a conditional loop whose condition happens to be always true sounds to me like a bug or a subversion (we intend this loop to stop when condition X becomes false, but bwahaha I arranged for X to never become false!). When a loop is *deliberately* meant to be infinite, I see a conditionless loop as a more faithful representation of that intent. Therefore I prefer `for(;;)` over any of the `while(true)`, `while(1)`, etc., variations. It conveys intent in a more straightforward, up-front way. If it helps you stomach it, you could interpret the `(;;)` as a funny way of saying "ever", so in essence you're saying `for-ever { ... }`. T -- Computers shouldn't beep through the keyhole.On 25.11.2016 11:33, Claude wrote:Probably the complete lack of a condition to test in for(;;). I confess that I was shocked when I found out that it was legal to have a for loop without a condition. That seems like doing while() or if(), which makes no sense.... Between "for(;;)", "while(true)" and "do while(true)", I would use the "while (true) { }" for pure readability and semantic reasons. ...What semantic reasons?
Nov 25 2016
I don't mean an infinite loop for (;;), and violation of the concepts of structured programming, which put forward Dijkstra. for (;;) { ... if (condition) { break; } ... } outer: for (;;) { ... if (condition) { goto outer; } ... } I.e. in system programming and I want to use `break` or `goto`, because here we use imperative rather than declarative approach. The following question arises. Are structured programming concept of Dijkstra's right for writing system software?
Nov 25 2016
On 11/24/2016 05:09 PM, Dennis Ritchie wrote:On Thursday, 24 November 2016 at 22:04:00 UTC, LiNbO3 wrote:Personal preference. Nothing more. Programmers have far better things to do that fret over the relative merits of two identical constructs that have no relative (de)merits over each other.As you can see [1] the `while (true)` is lowered into `for (;true;)` so it's all about what construct pleases you the most. [1] https://github.com/dlang/dmd/blob/cd451ceae40d04f7371e46df1c955fd914f3085f/src/statementsem.d#L357OK, thanks. The next question is: What principles guided when choosing between `for (;;) { ... }` and `while (true) { ... }` ?
Dec 01 2016
On Thu, Dec 01, 2016 at 11:23:26AM -0500, Nick Sabalausky via Digitalmars-d wrote:On 11/24/2016 05:09 PM, Dennis Ritchie wrote:[...]Far better things? You mean, like having endless discussions about a controversial D topic on this forum while procrastinating on the actual writing of code? Yeah, I can see that. :-P T -- It is of the new things that men tire --- of fashions and proposals and improvements and change. It is the old things that startle and intoxicate. It is the old things that are young. -- G.K. ChestertonThe next question is: What principles guided when choosing between `for (;;) { ... }` and `while (true) { ... }` ?Personal preference. Nothing more. Programmers have far better things to do that fret over the relative merits of two identical constructs that have no relative (de)merits over each other.
Dec 01 2016
Why you consider only 2 options? Use "do {} while (true);" :-)
Nov 24 2016
On 25/11/2016 8:27 PM, unDEFER wrote:Why you consider only 2 options? Use "do {} while (true);" :-)The condition only executes after a single iteration. So it is not the same code flow.
Nov 25 2016
On Friday, 25 November 2016 at 08:46:24 UTC, rikki cattermole wrote:On 25/11/2016 8:27 PM, unDEFER wrote:For an the usecase infinite-loop the code has the same effect. And will translate to the same machine-code, hopefully.Why you consider only 2 options? Use "do {} while (true);" :-)The condition only executes after a single iteration. So it is not the same code flow.
Nov 25 2016