I would prefer `ifNone:` instead of `otherwise` as it makes the semantics clearer IMHO.
-Thorsten > Am 03.02.2017 um 12:50 schrieb Haravikk via swift-evolution > <[email protected]>: > > >> On 2 Feb 2017, at 13:44, Derrick Ho <[email protected]> wrote: >> >> Maybe we can add a new parameter "otherwise" to the forEach method >> >> [1,2,3,4].forEach({ >> // do something >> } >> , otherwise: { >> // do something if it is an empty array >> }) > > That could be a decent compromise; just tried a simple extension and the > following seems to work quite nicely: > > extension Sequence { > func forEach(_ body: (Iterator.Element) throws -> Void, otherwise: () > throws -> Void) rethrows -> Void { > var it = self.makeIterator() > if let first = it.next() { > try body(first) > while let current = it.next() { try body(current) } > } else { try otherwise() } > } > } > > let names = ["foo", "bar", "baz"], empty:[String] = [] > names.forEach({ print($0) }, otherwise: { print("no names") }) > empty.forEach({ print($0) }, otherwise: { print("no names") }) > > Of course it lacks the ability to use continue or break, so the question is; > does it add enough utility to add, or is it better left to developers to > extend themselves? > >>> On Thu, Feb 2, 2017 at 6:31 AM Haravikk via swift-evolution >>> <[email protected]> wrote: >>> I'm of two minds on this feature; I kind of support the idea of the >>> construct, especially because there are some behind the scenes >>> optimisations it can do, and it can look neater. >>> However, I'm not at all keen on the re-use of else; if there were a better >>> keyword I might suppose that, for example "empty" or something like that, >>> but nothing I can think of feels quite right. >>> >>> I mean, when it comes down to it the "best" way to write the loop is like: >>> >>> var it = names.makeIterator() >>> if let first = it.next() { >>> print(first) >>> while let current = it.next() { print(current) } >>> } else { print("no names") } >>> >>> However this is a horrible thing to do in your own code, especially if the >>> loop body is larger than one line, but is just fine if it's done behind the >>> scenes for you (complete with unwrapping of the iterators if their type is >>> known). >>> >>> Which is why I kind of like the idea of having the construct itself; >>> otherwise, like others, I use the less "correct" option like so (for >>> sequences): >>> >>> var empty = true >>> for name in names { print(name); empty = false } >>> if empty { print("no names") } >>> >>> At which point I simply hope that the compiler optimises away the >>> assignment (since it only actually does something on the first pass). >>> >>> So yeah, I can see a use for it, but I'd prefer a construct other than >>> for/else to do it; at the very least a different keyword, as there's the >>> possibility we could also have a while/else as well and it would need to be >>> very clear, which I don't feel that for/else is. >>> >>>>> On 2 Feb 2017, at 11:06, Jeremy Pereira via swift-evolution >>>>> <[email protected]> wrote: >>>>> >>>>> >>>>> On 1 Feb 2017, at 18:29, Chris Davis via swift-evolution >>>>> <[email protected]> wrote: >>>>> >>>>> ah! I forgot about the break semantics, that’s definitely one for the con >>>>> list. >>>>> >>>>> I like Nicolas’ solution, clear to read. >>>>> >>>>>> On 1 Feb 2017, at 18:18, Nicolas Fezans <[email protected]> wrote: >>>>>> >>>>>> I tend to write this kind of treatment the other way around... >>>>>> >>>>>> if names.isEmpty { >>>>>> // do whatever >>>>>> } // on other cases I might have a few else-if to treat other cases that >>>>>> need special treament >>>>>> else { >>>>>> for name in names { >>>>>> // do your thing >>>>>> } >>>>>> } >>>> >>>> >>>> This only works if you know the size of the sequence before you start >>>> iterating it. You can, for example, iterate a lazy sequence and >>>> calculating its size before iterating it defeats the object.Thus for { … } >>>> else { … } where the else block only executes if the for block was never >>>> executed does have some utility. >>>> >>>> However, I am not in favour adding it. The same functionality can be >>>> achieved by counting the number of iterations and testing the count >>>> afterwards (or by using a boolean). It takes a couple of extra lines of >>>> code and an extra variable, but I think that is a Good Thing. It’s more >>>> explicit and (as the Python example shows) there could be hidden >>>> subtleties that confuse people if for … else … is badly designed. Also, in >>>> many cases, I would argue that treating the zero element sequence >>>> differently to the n > 0 element sequence is a code smell. About the only >>>> use-case I can think of off the top of my head is UI presentation e.g. >>>> “your search didn’t return any results” instead of a blank page. >>>> >>>> Talking of Python, Swift is not Python and the argument not to implement a >>>> feature because its semantics conflict with the semantics of a similar >>>> looking feature in another language is bogus. I don’t see the Python for … >>>> else being different (and having looked it up to see what you all were >>>> talking about, my opinion is that the Python for … else is a disaster) as >>>> being a legitimate con to this cleaner and more logical idea in Swift. >>>> >>>> >>>> _______________________________________________ >>>> 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
