On 31 Dec 2015, at 9:41 PM, ilya via swift-evolution < > swift-evolution@swift.org> 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.
let block: Int -> Void = ...
[1,2,3].map(block)
This will hold true for any advanced variant of map.
Ilya.
On Thu, Dec 31, 2015 at 10:30 Dave Abrahams via swift-evolution < > swift-evolution@swift.org> wrote:
-Dave
On Dec 30, 2015, at 8:48 PM, Kevin Ballard via swift-evolution < >> swift-evolution@swift.org> 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 < >> swift-evolution@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 = 0, @noescape mapper: (controller: MapController<E,
>, 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
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
_______________________________________________
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