[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