I'm replying on Swift-Users and bcc'ing in Swift-Evolution to comply with the core team's request to focus SE on the current mission statement.
At some point soon, Russ Bishop's PR https://github.com/apple/swift/pull/3600 <https://github.com/apple/swift/pull/3600> will be incorporated into Swift 3. This PR adds `prefix(while:)` and `drop(while:)` to finish implementing SE-0045. Once that's done, you can combine `sequence(first:, next:)` and `prefix(while:)` to into a single function `sequence(first:, next:, while:)` like this: public func sequence<T>(first: T, next: (T) -> T?, while test: (T) -> Bool) -> UnfoldSequence<T, UnfoldSequence<T, (T?, Bool)>> { return sequence(first: first, next: next).prefix(while: test) } The combined sequence/prefix call allows you to create loops like this: for outerIndex in sequence(first: 1, next: { $0 * 2 }, while: { $0 <= 64 }) { for innerIndex in sequence(first: 1, next: { $0 * 2 }, while: { $0 <= 64 }) { print(outerIndex, innerIndex) } } These loops can be nested. break and continue work. You can use tuples for multiple arguments. While I'd like to see a combined form adopted into Swift 4b (the deferred "sugar"), it isn't a high priority. -- E > On Jul 31, 2016, at 7:18 AM, Ted F.A. van Gaalen via swift-evolution > <swift-evolution@swift.org> wrote: > > >> On 31.07.2016, at 04:28, jaden.gel...@gmail.com >> <mailto:jaden.gel...@gmail.com> wrote: >> >> What benefit do Iterator2D and Iterator3D provide that nesting does not? > Hi Jaden, > well, simply because of hiding/enclosing repetitive functionality > like with every other programming element is convenient, > prevents errors and from writing the same over and over again. > That is why there are functions. > but you already know that, of course. > Kind Regards > TedvG > >> >> On Jul 30, 2016, at 1:48 PM, Ted F.A. van Gaalen via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >>> Hi Chris, >>> >>> thanks for the tip about Hirundo app! >>> >>> A positive side-effect of removing the classical for;; loop >>> (yes, it’s me saying this :o) is that it forces me to find >>> a good and generic equivalent for it, >>> making the conversion of my for;;s to 3.0 easier. >>> which is *not* based on collections or sequences and >>> does not rely on deeper calls to Sequence etc. >>> >>> so, I’ve made the functions [iterator, iterator2D, iterator3D] (hereunder) >>> wich btw clearly demonstrate the power and flexibility of Swift. >>> >>> Very straightforward, and efficient (i assume) just like the classical >>> for;; loop. >>> It works quite well in my sources. >>> >>> As a spin-off, I’ve extended these to iterators for matrices 2D and cubes? >>> 3D... >>> >>> Question: >>> Perhaps implementing “multi dimensional iterator functions >>> in Swift might be a good idea. so that is no longer necessary to >>> nest/nest/nest iterators. >>> >>> Met vriendelijke groeten, sorry for my “intensity” in discussing the >>> classical for;; >>> I'll have to rethink this for;; again.. >>> Thanks, Ted. >>> >>> Any remarks ( all ), suggestions about the code hereunder: ? >>> >>> protocol NumericType >>> { >>> func +(lhs: Self, rhs: Self) -> Self >>> func -(lhs: Self, rhs: Self) -> Self >>> func *(lhs: Self, rhs: Self) -> Self >>> func /(lhs: Self, rhs: Self) -> Self >>> func %(lhs: Self, rhs: Self) -> Self >>> } >>> >>> extension Double : NumericType { } >>> extension Float : NumericType { } >>> extension CGFloat: NumericType { } >>> extension Int : NumericType { } >>> extension Int8 : NumericType { } >>> extension Int16 : NumericType { } >>> extension Int32 : NumericType { } >>> extension Int64 : NumericType { } >>> extension UInt : NumericType { } >>> extension UInt8 : NumericType { } >>> extension UInt16 : NumericType { } >>> extension UInt32 : NumericType { } >>> extension UInt64 : NumericType { } >>> >>> >>> /// Simple iterator with generic parameters, with just a few lines of code. >>> /// for most numeric types (see above) >>> /// Usage Example: >>> /// >>> /// iterate(xmax, { $0 > xmin}, -xstep, >>> /// {x in >>> /// print("x = \(x)") >>> /// return true // returning false acts like a break >>> /// } ) >>> /// >>> /// -Parameter vstart: Initial value >>> /// -Parameter step: The iteration stepping value. >>> /// -Parameter test: A block with iteration test. e.g. {$0 > 10} >>> /// >>> /// -Parameter block: A block to be executed with each step. >>> /// The block must include a return true (acts like "continue") >>> /// or false (acts like "break") >>> /// -Please Note: >>> /// There is minor precision loss ca: 1/1000 ... 1/500 >>> /// when iterating with floating point numbers. >>> /// However, in most cases this can be safely ignored. >>> /// made by ted van gaalen. >>> >>> >>> func iterate<T:NumericType> ( >>> vstart: T, >>> _ vstep: T, >>> _ test: (T) -> Bool, >>> _ block: (T) -> Bool ) >>> { >>> var current = vstart >>> >>> while test(current) && block(current) >>> { >>> current = current + vstep >>> } >>> } >>> >>> >>> /// X,Y 2D matrix (table) iterator with generic parameters >>> func iterate2D<T:NumericType> ( >>> xstart: T, _ xstep: T, _ xtest: (T) -> Bool, >>> _ ystart: T, _ ystep: T, _ ytest: (T) -> Bool, >>> _ block: (T,T) -> Bool ) >>> { >>> var xcurrent = xstart >>> var ycurrent = ystart >>> >>> var dontStop = true >>> >>> while xtest(xcurrent) && dontStop >>> { >>> ycurrent = ystart >>> while ytest(ycurrent) && dontStop >>> { >>> dontStop = block(xcurrent, ycurrent) >>> ycurrent = ycurrent + ystep >>> } >>> xcurrent = xcurrent + xstep >>> } >>> } >>> >>> >>> /// X,Y,Z 3D (cubic) iterator with generic parameters: >>> >>> func iterate3D<T:NumericType> ( >>> xstart: T, _ xstep: T, _ xtest: (T) -> Bool, >>> _ ystart: T, _ ystep: T, _ ytest: (T) -> Bool, >>> _ zstart: T, _ zstep: T, _ ztest: (T) -> Bool, >>> _ block: (T,T,T) -> Bool ) >>> { >>> var xcurrent = xstart >>> var ycurrent = ystart >>> var zcurrent = zstart >>> >>> var dontStop = true >>> >>> while xtest(xcurrent) && dontStop >>> { >>> ycurrent = ystart >>> while ytest(ycurrent) && dontStop >>> { >>> zcurrent = zstart >>> while ztest(zcurrent) && dontStop >>> { >>> dontStop = block(xcurrent, ycurrent, zcurrent) >>> zcurrent = zcurrent + zstep >>> } >>> ycurrent = ycurrent + ystep >>> } >>> xcurrent = xcurrent + xstep >>> } >>> } >>> >>> >>> func testIterator() >>> { >>> iterate(0.0, 0.5, {$0 < 1000.00000} , >>> { value in >>> print("Value = \(value) ") >>> return true >>> } ) >>> >>> let startv: CGFloat = -20.0 >>> let stepv: CGFloat = 0.5 >>> >>> iterate(startv, stepv, {$0 < 1000.00000} , >>> { val in >>> print("R = \(val)") >>> return true >>> } ) >>> >>> let tolerance = 0.01 // boundary tolerance for floating point type >>> >>> iterate2D( 0.0, 10.0, { $0 < 100.0 + tolerance } , >>> 0.0, 5.0, { $0 < 50.0 + tolerance } , >>> {x,y in >>> print("x = \(x) y = \(y)") >>> return true // false from block stops iterating ( like >>> break) >>> } ) >>> >>> iterate3D( 0.0, 10.0, { $0 < 30.0 } , // x >>> 0.0, 5.0, { $0 < 20.0 } , // y >>> 10.0, -5.0, { $0 > -10.0 } , // z >>> {x,y,z in >>> print("x = \(x) y = \(y) z = \(z)") >>> if z < 0.0 >>> { >>> print ( "** z value \(z) is below zero! **" ) >>> >>> return false // (acts as break in for;;) >>> } >>> return true // return stmt is obligatory (continue) >>> } ) >>> } >>> >>> >>> >>> >>> >>> >>> >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution