[swift-evolution] C-style For Loops

Brent Royal-Gordon brent at architechies.com
Mon Dec 7 00:18:32 CST 2015


> Fun fact, you write (albiet with different syntax) C-style for-loops as library code:
> 
>> for i in CStyle(0, {$0 < 20}, {$0 += 1}) {
>>  // do something 20 times
>> }
> 
> Where CStyle is just a straightforward implementation of SequenceType. (Tuples allow for simultaneous iteration, which is usually when I end up with C-style for-loops)

I love the idea of this, but the syntax is remarkably ugly. (It’s actually even worse than you think, because inout closure parameters have to be declared with an exact type.) With a placeholder-based currying syntax, on the other hand…

	for i in CSequence(0, _ < 20, _ += 1) { … }

That’s not too shabby, is it?

	public struct CSequence <T>: SequenceType {
		private let initialValue: T
		private let testClosure: T -> Bool
		private let incrementClosure: (inout T) -> Void

		public init(_ initial: T, _ test: T -> Bool, _ increment: (inout T) -> Void) {
			initialValue = initial
			testClosure = test
			incrementClosure = increment
		}

		public func generate() -> CGenerator<T> {
			return CGenerator(self)
		}
	}

	public struct CGenerator<T>: GeneratorType {
		private let sequence: CSequence<T>
		private var value: T?
		
		private init(_ seq: CSequence<T>) {
			sequence = seq
		}
		
		public mutating func next() -> T? {
			if value != nil {
				sequence.incrementClosure(&value!)
			}
			else {
				value = sequence.initialValue
			}
			if sequence.testClosure(value!) {
				return value
			}
			else {
				return nil
			}
		}
	}

-- 
Brent Royal-Gordon
Architechies



More information about the swift-evolution mailing list