[swift-evolution] Revisiting 0004 etc. - Swift deprecations
Dany St-Amant
dsa.mls at icloud.com
Sun Apr 10 10:13:38 CDT 2016
> Le 2 avr. 2016 à 21:43, Andrew Bennett via swift-evolution <swift-evolution at swift.org> a écrit :
>
> On that note here is a convenient pattern I've used in the rare cases I haven't been able to convert to a "for in" syntax when refactoring:
>
> var i = 0
> while i < 10 {
> defer { i += 1 }
> print(i)
> }
>
> To be honest I don't really mind this syntax, I often found during refactoring:
> * the c-style "for" was broken up over multiple lines anyway
> * I wanted the last value of `i` outside the loop, so it was written "for ; check; incr"
> * It still works with continue, although it does increment "i" on break
>
Interesting pattern, it closely match with the "sugar" that C provides around ‘while’ in the form of 'for(;;)’
The following C snippet
#define INITIALIZER (i = 0)
#define TEST (i < 10)
#define STEPPER (i += 1)
for (INITIALIZER; TEST; STEPPER)
{
if (i % 2 == 0) { continue; }
if (i % 5 == 0) { break; }
printf("%d\n",i);
}
can be written (reusing the #define)
INITIALIZER;
while TEST
{
if (i % 2 == 0) { STEPPER; continue; }
if (i % 5 == 0) { break; }
printf("%d\n",i);
STEPPER;
}
Beside the break issue, making use of ‘defer’ causes the nested continue to misbehave:
var i = 0
loop_i:
while i < 10 {
defer { i += 1 }
defer { print("---",j) }
var j = 0
loop_j:
while j < 10 {
defer { j += 1 }
if j % 2 == 0 { continue loop_j }
if j % 5 == 0 { continue loop_i }
print(i,j)
}
}
In this example, the ‘continue loop_i’ does increase ‘j’, but I would not expect that; since C doesn't allow to directly continue an outer loop I cannot compare my opinion against the real world.
Should we pursue having a ‘defer(@oncontinue)’ or a new ‘continuer’ (don’t really like that name)?
With this lone new syntax, all the imaginable 'for(;;)’ can be blindly ported to Swift, with all the advantages and disadvantages of the C version. Reusing my #define as placeholders, any C-world ‘for(;;)’ can be written in Swift as:
INITIALIZER
while TEST
{
defer(@oncontinue) { STEPPER }
// Work load
}
In a nested loop environment, this could be used like:
var i = 0
loop_i:
while i < 10 {
defer(@onncontinue) { i += 1 }
var j = 0
loop_j:
while j < 10 {
defer(@oncontinue) { j += 1 }
if j % 2 == 0 { continue loop_j /* j += 1 */}
if j % 5 == 0 { continue loop_i /* i += 1, but NOT j += 1*/}
print(i,j)
// continue loop_j // implicit, so j += 1
}
// continue loop_i // implicit, so i += 1
}
Dany
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160410/1e11b882/attachment.html>
More information about the swift-evolution
mailing list