You make a good point. `forEach` is simple for people new to the language and is relatively innocuous. It is also a 'stepping stone drug' to using `map`, `filter`, etc. :)
Sent from my iPad > On 1 Jan 2016, at 11:55 AM, Tim Hawkins <[email protected]> wrote: > > Just my 2 cents, > > forEach is a simple concept to understand, it exists in most other languages > that have a language level understanding of containers, retaining it has no > downsides, but has the upside of making swift more approachable. > > 'map' on the otherhand may be much more powerful a construct, but it is less > famliar as a concept. > > Is there any reason why both cant coexist, with one being a simple form of > the other. > >> On Jan 1, 2016 7:31 AM, "Howard Lovatt via swift-evolution" >> <[email protected]> wrote: >> I suspect that if there were an 'advanced' `map` it would largely eliminate >> `forEach` since a main use of `forEach` is because of limitation in map like >> multiple returns, combined map and filtering, etc. >> >> The comment that you have to ignore a warning is however a valid point, >> perhaps like other languages, e.g. Java, you could have a >> `@suppress_unused_result_warning` annotation. >> >> Sent from my iPad >> >>> On 31 Dec 2015, at 9:41 PM, ilya via swift-evolution >>> <[email protected]> wrote: >>> >>> I like having separate forEach. As already said, forEach produces different >>> visual grouping of logic compared to for operator. It's especially useful >>> if you just pass a named function to it. >>> >>> forEach is also not the same as map: >>> >>> let block: Int -> Void = ... >>> [1,2,3].map(block) >>> >>> Here the result has the type [Void], not Void and the compiler correctly >>> produces a warning. We'd have to explicitly assign the result to silence >>> it, which now hides the fact that block wasn't producing anything in the >>> first place. >>> >>> This will hold true for any advanced variant of map. >>> >>> Ilya. >>>> On Thu, Dec 31, 2015 at 10:30 Dave Abrahams via swift-evolution >>>> <[email protected]> wrote: >>>> >>>> -Dave >>>> >>>>> On Dec 30, 2015, at 8:48 PM, Kevin Ballard via swift-evolution >>>>> <[email protected]> wrote: >>>>> >>>>> Swift didn't use to have forEach(). It was added fairly late, and I >>>>> suspect (though I don't actually know) that it was done so to appease >>>>> people who kept abusing map() for the same function, as well as the >>>>> die-hard everything-must-be-functional crowd. >>>> >>>> Those are two of the reasons. But the reason that put forEach over the >>>> line and convinced me to add it, just slightly, was syntactic: >>>> >>>> for x in some.very.long[chain] >>>> .of.map { $0 } >>>> .filter { something }.whatever { >>>> ... >>>> } >>>> >>>> reads "inside-out," like nested(free(function(calls())))) vs. >>>> >>>> some.very.long[chain] >>>> .of.map { $0 } >>>> .filter { something }.whatever >>>> .forEach { x in >>>> ... >>>> } >>>> >>>>> >>>>> Personally, I'd rather we didn't have it because it encourages people to >>>>> use it, but I suppose it's better to give people an appropriate tool than >>>>> to keep watching them abuse map(). >>>>> >>>>> -Kevin Ballard >>>>> >>>>>> On Wed, Dec 30, 2015, at 04:50 PM, Craig Cruden via swift-evolution >>>>>> wrote: >>>>>> I don’t see the benefit of taking a simple declarative expression (map, >>>>>> flatMap, filter) and turning it into a complicated imperative/iterative >>>>>> loop. You already have the ability to iterate through a set and do >>>>>> whatever you want to do with with whatever logic you want to use using. >>>>>> I would have no problem for the most part removing foreach - it is more >>>>>> of a convenience method for doing an iterative loop through a collection >>>>>> - and to be quite honest rarely use outside of maybe putting in a print >>>>>> statement temporarily in there (but more often just turn the resulting >>>>>> set into comma delimited output and printing it). >>>>>> >>>>>> >>>>>>> On 2015-12-31, at 5:10:22, Howard Lovatt via swift-evolution >>>>>>> <[email protected]> wrote: >>>>>>> >>>>>>> >>>>>>> You could replace `forEach` with a supped up `map` that also allowed >>>>>>> `break` and `continue`. The following library function gives `continue` >>>>>>> and `break` and also combines `repeat`, `times`, `forEach`, `filter`, >>>>>>> `flatMap`, and `map` into one: >>>>>>> >>>>>>> public final class MapController<E, R> { >>>>>>> var results = [R]() >>>>>>> >>>>>>> var isContinuing = true >>>>>>> >>>>>>> init<C: CollectionType where C.Generator.Element == E>(_ collection: C, >>>>>>> sizeEstimate: Int = 0, @noescape mapper: (controller: MapController<E, >>>>>>> R>, element: E) throws -> R?) rethrows { >>>>>>> results.reserveCapacity(sizeEstimate) >>>>>>> for var generator = collection.generate(), element = generator.next(); >>>>>>> element != nil && isContinuing; element = generator.next() { >>>>>>> let result = try mapper(controller: self, element: element!) >>>>>>> if let actualResult = result { >>>>>>> results.append(actualResult) >>>>>>> } >>>>>>> } >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> extensionCollectionType { >>>>>>> /// Controllable `map`, additional controls beyond simple `map` are: >>>>>>> /// >>>>>>> /// 1. Continue without returning a result (`return nil`) >>>>>>> /// 2. Return multiple results (`control.results += [...]` then >>>>>>> `return nil`) >>>>>>> /// 3. Break (`control.isContinuing = false` then `return nil`) >>>>>>> /// >>>>>>> /// These additional controls allow this `map` to function like >>>>>>> `repeat`, `times`, `forEach`, `filter`, `flatMap`, and `map` combined >>>>>>> into one as well as providing an early termination (break). >>>>>>> @warn_unused_result func map<R>(sizeEstimate sizeEstimate: Int = 0, >>>>>>> @noescape mapper: (controller: MapController<Self.Generator.Element, >>>>>>> R>, element: Self.Generator.Element) throws -> R?) rethrows -> [R] { >>>>>>> return try MapController(self, sizeEstimate: sizeEstimate, mapper: >>>>>>> mapper).results >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> // Demonstration of full functionality including continue, break, and >>>>>>> multiple returns >>>>>>> var result = (0 ..< 5).map { (control, index) -> Int? in >>>>>>> switch index { >>>>>>> case 1: >>>>>>> returnnil// Continue - skip 1 (`filter`) >>>>>>> case 2: >>>>>>> control.results.append(2) // Yield two results - this one and >>>>>>> the 'return’ yield (`flatMap`) >>>>>>> case 3: >>>>>>> control.isContinuing = false// Break after next yield - which >>>>>>> could be `return nil` if there are no more results >>>>>>> default: >>>>>>> break >>>>>>> } >>>>>>> return index // Yield next result - except for case 1 all the above >>>>>>> yield `index` >>>>>>> } >>>>>>> print(result) // prints `[0, 2, 2, 3]` note missing "1", double "2", >>>>>>> and last is "3" >>>>>>> >>>>>>> // Demonstration of `repeat`/`forEach`/`times` like usage - note `(_, >>>>>>> _) -> Void?` >>>>>>> result = [Int]() >>>>>>> (0 ..< 3).map { (_, _) -> Void? in >>>>>>> result.append(1) // Do whatever - in this case append to a global >>>>>>> returnnil// Don't yield any results >>>>>>> } >>>>>>> print(result) // prints `[1, 1, 1]` >>>>>>> >>>>>>> Would this be a superior alternative to both `forEach` and `times` in >>>>>>> the library and `repeat` as a language feature? >>>>>>> >>>>>>> Sent from my iPad >>>>>>> >>>>>>> _______________________________________________ >>>>>>> swift-evolution mailing list >>>>>>> [email protected] >>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> swift-evolution mailing list >>>>>> [email protected] >>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>> >>>>> >>>>> _______________________________________________ >>>>> swift-evolution mailing list >>>>> [email protected] >>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>> >>>> >>>> >>>> _______________________________________________ >>>> swift-evolution mailing list >>>> [email protected] >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] >>> https://lists.swift.org/mailman/listinfo/swift-evolution >> >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution >>
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
