[swift-evolution] Review for: Remove C-style for-loops with conditions and incrementers

Michel Fortin michel.fortin at michelf.ca
Mon Dec 7 21:11:48 CST 2015


Le 7 déc. 2015 à 21:03, Joe Groff <jgroff at apple.com> a écrit :
> A more accurate (but not particularly pretty) substitution would be to perform the increment as part of the condition:
> 
> while { i = increment(i); return cond(i) }() {
> }

That's buggy (and also does not compile). What you want is this:

var i = 0
var first = true
while ({ () -> Bool in if first { first = false } else { i = increment(i) }; return cond(i) }()) {
}

Interestingly, this behaves correctly with both continue, break, and throw. It's not pretty, but this struct will make a little bit easier on the eye:

/// Provide a suitable condition for recreating the control flow of a C-style `for`
/// loop within a `while` loop.
///
///     var loop = CForLoop()
///     var i = 0
///     while loop.test(i < 2, {i += 1}) { ... }
///
/// - Note: You have to make a new controller each time you start a loop.
struct CForLoop {

	/// Flag to prevent the increment part from executing on the first iteration of 
	/// the loop.
	private var first = true

	/// If this is the first call of test, simply evaluate `predicate` and return
	/// its value. Subsequent calls will execute `increment` before evaluating
	/// `predicate`.
	/// - Parameter predicate: The test condition that must be true for the loop to
	///   continue. This is the second statement in a C-style `for` loop.
	/// - Parameter increment: The code to execute just before re-evaluating the
	///   predicate at the end of one loop iteration. This is the third statement
	///   of a C-style `for` loop.
	/// - Returns: The value returned by predicate. This value should be used as
	///   the condition in a `while` loop.
	mutating func test(@autoclosure predicate: () -> Bool, _ increment: () -> ()) -> Bool {
		if first {
			first = false
		} else {
			increment()
		}
		return predicate()
	}
}


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



More information about the swift-evolution mailing list