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

Reply via email to