| Thread overview | |||||||||
|---|---|---|---|---|---|---|---|---|---|
|
June 19, 2012 for() with 4 arguments to allow postcondition | ||||
|---|---|---|---|---|
| ||||
I have a suggestion for D (which might make it into C/C++ as well, but I thought D would be a more accessible place to suggest it): for(initializer; precondition; postcondition; increment) would allow avoiding a useless comparison before the start of the first iteration of a "for" loop in those cases where the programmer knows the loop will always iterate at least once. This new 4-argument version could exist alongside the old 3-argument version. An extra semicolon is all it would take to turn a precondition into a postcondition. So now you could still write: for (i = 0; i < 10; ++i) // old syntax still available, *hopefully* optimized by compiler but you could just add an extra semicolon to explicitly avoid comparing 0 to 10: for (i = 0; ; i < 10; ++i) // new syntax avoids comparing 0 to 10 Of course in this simple case, the compiler will probably optimize the loop anyway so there will be no difference in the resulting code (at least if "i" is an int), but replace 10 by a variable which you know to be greater than 0, or use a custom class for the iterator, or replace the comparison with a function call, and the only way to avoid checking the condition before the first iteration is by using "do while()" which is less readable. Obviously, using both a precondition AND a postcondition would not be recommended for readability although it would be legal and might be useful in obfuscation contests. Feel free to grab this idea and propagate it to wherever you like. I would love to see this feature turn up in D and maybe in C and C++ as well. And it seems very easy to implement. | ||||
June 19, 2012 Re: for() with 4 arguments to allow postcondition | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Michel Colman | On 2012-06-19 12:51, Michel Colman wrote: > I have a suggestion for D (which might make it into C/C++ as > well, but I thought D would be a more accessible place to suggest > it): > > for(initializer; precondition; postcondition; increment) > > would allow avoiding a useless comparison before the start of the > first iteration of a "for" loop in those cases where the > programmer knows the loop will always iterate at least once. This > new 4-argument version could exist alongside the old 3-argument > version. An extra semicolon is all it would take to turn a > precondition into a postcondition. Isn't this what a do-while loop is for, or am I missing something? -- /Jacob Carlborg | |||
June 19, 2012 Re: for() with 4 arguments to allow postcondition | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Michel Colman | On 06/19/2012 12:51 PM, Michel Colman wrote: > I have a suggestion for D (which might make it into C/C++ as > well, but I thought D would be a more accessible place to suggest > it): > > for(initializer; precondition; postcondition; increment) > > would allow avoiding a useless comparison before the start of the > first iteration of a "for" loop in those cases where the > programmer knows the loop will always iterate at least once. This > new 4-argument version could exist alongside the old 3-argument > version. An extra semicolon is all it would take to turn a > precondition into a postcondition. > > So now you could still write: > > for (i = 0; i < 10; ++i) // old syntax still available, > *hopefully* optimized by compiler > foreach(i; 0..10) > but you could just add an extra semicolon to explicitly avoid > comparing 0 to 10: > > for (i = 0; ; i < 10; ++i) // new syntax avoids comparing 0 to 10 > > Of course in this simple case, the compiler will probably > optimize the loop anyway so there will be no difference in the > resulting code (at least if "i" is an int), but replace 10 by a > variable which you know to be greater than 0, or use a custom > class for the iterator, or replace the comparison with a function > call, and the only way to avoid checking the condition before the > first iteration is by using "do while()" which is less readable. > > Obviously, using both a precondition AND a postcondition would > not be recommended for readability although it would be legal and > might be useful in obfuscation contests. > > Feel free to grab this idea and propagate it to wherever you > like. I would love to see this feature turn up in D and maybe > in C and C++ as well. You have missed to describe the exact semantics of the construct. Should it be like this? for(initializer; condition1; condition2; increment) => for(initializer;;increment){ if(!condition1) break; body; if(!condition2) break; } > And it seems very easy to implement. > It is. But in ~16'000 LOC, I have used 56 'for' statements. 3 of them have the property that they always execute the first loop iteration and this is not immediately obvious to the compiler. Therefore, I think the proposed syntax sugar is useless. | |||
June 19, 2012 Re: for() with 4 arguments to allow postcondition | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Michel Colman | On 6/19/2012 3:51 AM, Michel Colman wrote:
> So now you could still write:
>
> for (i = 0; i < 10; ++i) // old syntax still available,
> *hopefully* optimized by compiler
I recommend coding up this example, submitting it to dmd with the -O switch, and examining the output.
| |||
June 22, 2012 Re: for() with 4 arguments to allow postcondition | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | > Isn't this what a do-while loop is for, or am I missing something? Well, yes, but then you don't need the regular "for" loop either. After all, isn't that what a "while" loop is for? The big advantage of "for" is that you can see at a glance what the initialisation, condition(s) and increments are. It describes the whole loop in one statement. That's the only reason why it was invented in the first place, because the language technically does not need it. You can even declare the variable right there so its scope is limited to the loop. With a do-while, you first initialize the variable before the loop (outside of it), then add the increment just before the end (many pages later, perhaps), and the condition at the very end. It's all over the place. > foreach(i; 0..10) I know my simple example would be optimized, and can indeed be written with a foreach as well. But if you use some custom class as the variable, or a pointer, it won't be. For example, turn i into a Bigint. Or for an entirely different example: for (Display * d = firstDisplay; d != 0; d = nextDisplay) if you have already established that at least one display is present. Or even simpler: for (int i = 1; i <= 0x10000000; i <<= 1) I bet this won't be optimized on many compilers. And all it would take is one extra semicolon: for (Display * d = firstDisplay; ; d != 0; d = nextDisplay) for (int i = 1; ; i <= 0x10000000; i <<= 1) to tell the compiler to skip the condition before the first iteration. > for(initializer;;increment){ > if(!condition1) break; > body; > if(!condition2) break; >} Yes, that's exactly what I meant. Michel | |||
June 22, 2012 Re: for() with 4 arguments to allow postcondition | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Michel Colman | On 06/22/2012 08:57 PM, Michel Colman wrote: >> Isn't this what a do-while loop is for, or am I missing something? > > Well, yes, but then you don't need the regular "for" loop either. After > all, isn't that what a "while" loop is for? > > The big advantage of "for" is that you can see at a glance what the > initialisation, condition(s) and increments are. It describes the whole > loop in one statement. That's the only reason why it was invented in the > first place, because the language technically does not need it. You can > even declare the variable right there so its scope is limited to the > loop. With a do-while, you first initialize the variable before the loop > (outside of it), then add the increment just before the end (many pages > later, perhaps), and the condition at the very end. It's all over the > place. > >> foreach(i; 0..10) > > I know my simple example would be optimized, and can indeed be written > with a foreach as well. But if you use some custom class as the > variable, or a pointer, it won't be. For example, turn i into a Bigint. foreach-range works with custom types. > Or for an entirely different example: > > for (Display * d = firstDisplay; d != 0; d = nextDisplay) > > if you have already established that at least one display is present. > If firstDisplay is trivially non-null, the compiler will remove the comparison. Furthermore, the additional comparison is extremely cheap and will likely be completely unnoticeable. > Or even simpler: > > for (int i = 1; i <= 0x10000000; i <<= 1) > > I bet this won't be optimized on many compilers. > I bet this is optimized on any halfway decent optimizing compiler. This is the kind of simple optimization compilers are good at. > And all it would take is one extra semicolon: > > for (Display * d = firstDisplay; ; d != 0; d = nextDisplay) > for (int i = 1; ; i <= 0x10000000; i <<= 1) > > to tell the compiler to skip the condition before the first iteration. > The examples do not make a compelling case. | |||
June 22, 2012 Re: for() with 4 arguments to allow postcondition | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Michel Colman | I don't understand why people even still use the 'for' statement in D. I know there's probably some situations where 'foreach' wont work... but honestly I don't think I've ever come across any yet, and foreach syntax is so much easier to understand at a glance. I think people still just write 'for' loops cause they're use to it from C/C++ The only thing that would be nice, but completely unnecessary, is sugar for iota() and retro(): foreach (i; 0 .. 10, 2) foreach (i; 10 .. 0, -2) becomes: foreach (i; iota(0, 10, 2)) foreach (i; iota(0, 10, 2).retro()) | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply