[swift-evolution] C-style For Loops

Michel Fortin michel.fortin at michelf.ca
Sun Dec 6 20:10:50 CST 2015


Le 6 déc. 2015 à 16:08, ilya <ilya.nikokoshev at gmail.com> a écrit :

> There are a couple of ways of solving this issue:
> 
> 1 refactor to where loop first, then convert to Swift 

This assumes 1) that you have a working toolchain to compile, execute, and test the original code, and 2) that the other language has a way to express the loop in a similar way to Swift, or something close enough.


> 2 leave a fixit in Xcode that will perform while loop conversion 

As it was pointed out earlier, converting to a while loop requires duplication of the "increment" part of the loop everywhere there is a `continue` inside the loop. While you could make a fixit that correctly does this, I would argue that duplicating code shouldn't be done so lightly (someone will have to edit or maintain it afterwards). It's unclear to me what else could be done here however, as I can't think of a refactoring that would prevent code duplication. (And defer shouldn't be used here because it has a different behaviour when an exception is thrown.)

The fixit probably should also introduce a do{} block to correctly scope the loop variable and avoid clashes with the surrounding context.

It remains that even with a fixit that changes the code like this, the various differences it'll create in line count, increment expression placement, indentation, and sometime duplicated code, are going to impair your ability to compare the two loops side by side when hunting for porting bugs. Also the Swift version, the one that compiles thanks to a fixit, will simply be less readable... to the point that it'll generally be better to just do the refactoring as you port, despite the downsides.

Before fixit:

	for var i = 10; i >= 0; i -= 1 {
		if i == 5 {
			continue
		}
		for var j = 100; i >= 0; j -= 2 {
			print("\(i) \(j)")
		}
	}

After fixit:

	do {
		var i = 10
		while i >= 0 {
			if i == 5 {
				i -= 1
				continue
			}
			do {
				var j = 100;
				while j >= 0 {
					print("\(i) \(j)")
					j -= 2
				}
			}
			i -= 1
		}
	}


-- 
Michel Fortin
michel.fortin at michelf.ca
https://michelf.ca



More information about the swift-evolution mailing list