> On 01.08.2016, at 17:45, Saagar Jha <[email protected]> wrote: > > With your method, don't you need to write a new method for every dimension? Hi Saagar,
Yes, one could solve this by writing a function that propagates though all iteration levels, possibly recursively, I might try to implement that. left “as an exercise to the astute reader” :o) Kind regards Ted > On Mon, Aug 1, 2016 at 08:43 Ted F.A. van Gaalen via swift-users > <[email protected] <mailto:[email protected]>> wrote: > Hi Erica > > That would also be a workable solution, but imho still too tedious as > it has been so for many years, with nested iteration statements… > many times this is for;; for;; for tables and for;;for;;for;; for 3D > structuring. > > > Swift offers nice features (like protocols and generics as you know) to > improve this. > > - I no longer have to nest for;; s so, Now I rather do this: > Your example can already be coded like this: > > iterate2D( 1, 2, { $0 < 64 } , > 1, 2, { $0 < 64 } , > {outerIndex,innerIndex in > print (outerIndex,InnerIndex) > > return true // Obligatory. return “false" to break > } ) > > With no chances in Swift, this already works like a charm! > Imho much more readable and compact, > > Uses - AFAICS from a programmers’s perspective - no > underlying deep collection based coding with Sequence. etc. > > I am already deploying it in my own apps e.g. l > (replaced for;; for;; for;; in the app) > > By using this new iterator…() functions my coding gets leaner > and errors are easier to spot. > > Actual working code with Swift 2.x here: > > func generateTiles() > { > let w: Float = 20 // tile size > let h: Float = 5 > let l: Float = 5 > > let xstart: Float = -120 > let ystart: Float = -60 > let zstart: Float = -10 > > let xend: Float = 120 > let yend: Float = 60 > let zend: Float = 10 > > let tolerance:Float = 0.001 // float drift compensation > > iterate3D( xstart, w * 1.2, { $0 < xend + tolerance } , > ystart, h * 1.2, { $0 < yend + tolerance } , > zstart, l * 1.2, { $0 < zend + tolerance } , > { > x,y,z in > self.addTile(x,y,z, > w,h,l) > return true > } ) > } > > This generates a group of blocks or tiles in my Apple TV app (under > construction) > like the one you can see in the image “Cloinckz” on my website www.tedvg.com > <http://www.tedvg.com/>. > > I also prefer the one dimensional iterate(.. too above the for;; or stride() > > One could extend these iterator…() functions by adding closures for pre and > post iteration handling, > like for printing headers and footers before and/or after a complete [inner] > iteration. > > Note that breaking with *return false* -which is equivalent to the “break” > stmt in > a classical for;; - does not only leave a nested iteration, but also the > outer ones. > (maybe a TODO to make individual level- break possible) As it is now, If one > wants to break at the deep iteration level, then one should nest this using > 1D iterators. > > > Anyway, this is just a thought starting to think about multi-dimensional > iterators, > and other (encapsulation?) of multi dimensional data as well. > In any case for 2D because table data is used very frequently in many apps. as > most data are in tables. > > You won’t believe this :o) but in a sense I might not make so much fuzz > anymore > to keep the for;; as this proves to me that I can solve things much better > that I thought. > So, I have to rethink this. > > Kind Regards > Ted > www.ravelnotes.com <http://www.ravelnotes.com/> > > > > > > > >> On 31.07.2016, at 18:33, Erica Sadun <[email protected] >> <mailto:[email protected]>> wrote: >> >> 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 >>> <[email protected] <mailto:[email protected]>> wrote: >>> >>> >>>> On 31.07.2016, at 04:28, [email protected] >>>> <mailto:[email protected]> 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 >>>> <[email protected] <mailto:[email protected]>> 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 >>>>> [email protected] <mailto:[email protected]> >>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] <mailto:[email protected]> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> > > _______________________________________________ > swift-users mailing list > [email protected] <mailto:[email protected]> > https://lists.swift.org/mailman/listinfo/swift-users > <https://lists.swift.org/mailman/listinfo/swift-users>
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
