On Thu, Feb 2, 2017 at 6:31 AM Haravikk via swift-evolution < swift-evolution@swift.org> 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 < > swift-evolution@swift.org> wrote:
On 1 Feb 2017, at 18:29, Chris Davis via swift-evolution < > swift-evolution@swift.org> 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 <nicolas.fezans@gmail.com> 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
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