[swift-evolution] Remove forEach?

Donnacha Oisín Kidney oisin.kidney at gmail.com
Wed Dec 9 12:33:30 CST 2015


Can’t most of this functionality be achieved with current Swift features, though? I mean, you could have the break within the type that the closure returns.

In the case of forEach, you could have it return a Bool, rather than Void, with true signifying break:

extension SequenceType {
  func forEachBreak(body: Generator.Element -> Bool) {
    for element in self {
      if body(element) {
        return
      }
    }
  }
}

[1, 2, 3, 4, 5, 6, 7, 8].forEachBreak { n in
  print(n)
  if n > 4 { return true }
  return false
}

For methods like map, you could have a version which takes a closure that returns an Optional: nil signifying a break. Or, You could add something like a takeWhile method to SequenceType. (which would probably be the easiest to understand)

I think that annotations like @noescape and throws have huge overhead in terms of added confusion, especially for beginners. If the objective is to improve the understandability of certain functions, I think that something like this:

sequence.takeWhile { $0 < 10 }.forEach { print($0) }

is a better option than swelling the signature of forEach to:

func forEach(@noescape body: (Self.Generator.Element) throws, breaks -> ()) rethrows

Oisin.

> On 9 Dec 2015, at 17:43, Matthew Johnson 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).
> 
> I missed this post the first time around.  Is a really great idea and is something I hoped we might get eventually.  It allows "control flow" functions to behave as expected.
> 
> I assume a caller could pass a non-breaking closure if desired just as we can pass a non-throwing closure if desired, right?
> ,
> How would break and continue interact with the caller of the closure?  It would need to implement the correct behavior of skipping to the next loop cycle or moving on to any post-loop logic.
> 
> How would this behave for a closure that is stored and called later, possibly asynchronously?  Or would it only be allowed on closures declared
> 
> Matthew
> _______________________________________________
> 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/89efe437/attachment.html>


More information about the swift-evolution mailing list