[swift-evolution] Remove forEach?

David Owens II david at owensd.io
Wed Dec 9 10:47:09 CST 2015


Another language construct seems a bit much for this, right? Maybe I’m missing something, but can’t we get the same behavior with an overload?

extension Array {
    func forEach<U>(body: (element: Element) throws -> U?) rethrows -> U? {
        for e in self {
            if let result = try body(element: e) { return result }
        }
        
        return nil
    }
}

func g(e: Int) -> Int? {
    if e == 2 { return e }
    return nil
}

let arr = [1, 2, 3]
arr.forEach { print($0) }
let result = arr.forEach(g)
result                           // has the value of 2


Now, Swift has some issues determining the types properly if you attempt to inline the g function at the forEach() callsite, but that can be fixed.

-David

> On Dec 9, 2015, at 4:40 AM, Stephen Celis via swift-evolution <swift-evolution at swift.org> wrote:
> 
>> On Dec 8, 2015, at 5:13 PM, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> Another direction you might take this is to make it a type annotation on the function type, like throws, so forEach has a type like this:
>> 
>> func forEach(body: (Element) breaks -> ())
>> 
>> and a closure that `breaks` has nonlocal behavior for break/continue/return (and is implied to be noescape and void-returning, I guess).
> 
> This is really interesting. Ruby provides similar functionality with its lambda vs. proc, but a type annotation is much more understandable. It could also imply @noescape automatically:
> 
>    func forEach(@canbreak body: Element -> Void)
> 
> Stephen
> _______________________________________________
> 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/20151209/8382bfcf/attachment.html>


More information about the swift-evolution mailing list