[swift-evolution] Remove forEach?

Kevin Ballard kevin at sb.org
Wed Dec 30 22:48:25 CST 2015


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.

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 <swift-
>> evolution at swift.org> 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 = , @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 = ,
>>> @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 = ( ..< 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]() ( ..< 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 swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _________________________________________________
> swift-evolution mailing list swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151230/6a774fc1/attachment.html>


More information about the swift-evolution mailing list