[Pitch] Retiring `where` from for-in loops

* Swift is explicitly a C-family language. In most or all other C-family
languages, for loop statements allow specification of conditions for
exiting the loop but not for filtering. Therefore, Swift's use of `where`
is unprecedented and needs to be learned anew by every user of Swift.

Swift may have some similarities with C, but the last thing anyone should
want is for it to be bound to C as a language.

That's not my argument at all. There are elements of syntax that are
commonly seen in languages that take inspiration from C. We can rightly say
that those are 'familiar' or 'precedented,' by which I mean that a
significant proportion of people who come to Swift will be familiar with
how they work. This is a consideration, though by no means determinative of
what features we should have.

By contrast, there are elements of syntax in Swift which are
'unprecedented.' Some of those support features unique to Swift, or
features that Swift deliberately makes more prominent--take, for example,
sugar for unwrapping optionals or a greatly expanded type system.

We have heard from the core team that the `where` clause was put into the
language in order to align with greatly expanded pattern matching
facilities, but this was abandoned. Thus it now falls into a second
category of 'unprecedented' syntax: a syntax with no parallels in other
languages that take inspiration from C, but which does not serve a purpose
that is unique to or uniquely emphasized in Swift.

Besides, the purpose of a for in loop is to iterate over elements in a

sequence, so filtering is very much a useful thing to do so itā€™s hardly
unprecedented, and itā€™s also a fairly common thing to want to do.

That's not what I mean by precedent--see above.

* The word "where" does not consistently imply `break` or `continue`. In
current Swift, `where` implies `break` in the context of a `while` loop and
`continue` in the context of a `for` loop. Some users intuitively guess the
correct meaning in each context, while others guess the wrong meaning.
Therefore, the only way to learn for sure what `where` means in any context
is to read the rulebook. That, by definition, means that this is
unintuitive.

This is an argument for renaming the where keyword on for loops to be more
clear, or to somehow integrate continue/break to be more explicit about
what the developer intends for it to do.

Sure: I conclude that the keyword should be *either* removed *or* reformed;
both outcomes could address the issue.

* There are other ways to break from a loop or continue to the next
iteration without performance penalty. Nearly all of these serve more
general purposes than a `where` clause.

This isnā€™t really an argument against the where clause; the where clause
is useful for common, simple cases, so itā€™s not surprising if more
complex/unusual cases canā€™t (or canā€™t easily) be handled by it. This is for
the simple cases where this isnā€™t an issue.

Some of these (such as `if` or `guard`) would already be familiar to a new
user before they encounter loops, assuming a typical order for learning a
programming language. Many of these (such as filtering methods on
collections, or simply `if`) would be familiar to a user of another
C-family language. Therefore, the `where` clause provides no independent
utility, is not more discoverable than its alternatives, and is not
required for progressive disclosure of an important facility to a learner
(i.e. a simplified syntax for those who may not be ready for the advanced
concepts needed to use a more fully-featured alternative).

Simplification isnā€™t just for the new users; all you need to know with
where is that itā€™s a shorthand for guard X else { continue }, for many
people this is intuitive enough, but if there are enough for whom it isnā€™t
then again thatā€™s an argument to tweak it to be more clear about what it
does, rather than remove it entirely.

The independent utility that it offers is being able to avoid if/guard
boilerplate at the start of your loop, but instead putting it on the same
line; in simple cases this can be nice and neat.

That is not at all 'utility.' It is tautologically true that if you have
two alternatives A and B, using A has the 'utility' that you don't have to
use B. And since the whole point here is that the word `break` or
`continue` is not implied by `where`, I argue that writing it out within a
`guard` statement isn't boilerplate but absolutely essential. By contrast,
I have argued that the `where` syntax is not 'nice' or 'neat.'

it has been used incorrectly by at least some users.

Every feature in every language "has been used incorrectly by at least
some users", should we just drop all programming languages?

Not every feature serves no independent purpose *and* is used incorrectly
by at least some users.

Itā€™s not as if users canā€™t make mistakes while using an inline if/guard
condition.

One that's not caught at compile time? Show me.

Again, this an argument that the meaning isnā€™t implicit enough, which is
just as well served by tweaking the syntax than removing it.

Again, I'd be happy tweaking the syntax to make it clear, if possible. If
not, I'd remove it.

Ā·Ā·Ā·

On Fri, Jun 10, 2016 at 7:18 AM, Haravikk <swift-evolution@haravikk.me> wrote:

On 10 Jun 2016, at 07:25, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

This is my stance as well and I reserve the right to flit between both choices until we've fully talked it through.

One more data point.

In the standard library there are just under 950 uses of "for in loops". There are 3 uses of "for in while" :

private/StdlibUnittest/StdlibUnittest.swift.gyb: for j in instances.indices where i != j {
public/core/Algorithm.swift: for value in rest where value < minValue {
public/core/Algorithm.swift: for value in rest where value >= maxValue {

-- Erica

Ā·Ā·Ā·

On Jun 10, 2016, at 8:02 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

On Fri, Jun 10, 2016 at 7:18 AM, Haravikk <swift-evolution@haravikk.me <mailto:swift-evolution@haravikk.me>> wrote:

* The word "where" does not consistently imply `break` or `continue`. In current Swift, `where` implies `break` in the context of a `while` loop and `continue` in the context of a `for` loop. Some users intuitively guess the correct meaning in each context, while others guess the wrong meaning. Therefore, the only way to learn for sure what `where` means in any context is to read the rulebook. That, by definition, means that this is unintuitive.

This is an argument for renaming the where keyword on for loops to be more clear, or to somehow integrate continue/break to be more explicit about what the developer intends for it to do.

Sure: I conclude that the keyword should be *either* removed *or* reformed; both outcomes could address the issue.

Actually a slight correction to that. I forgot to add the space after "in" on the first search. It's just over 600 and 3. Among the 600 are a few false positives but not many.

-- E

Ā·Ā·Ā·

On Jun 10, 2016, at 9:22 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

On Jun 10, 2016, at 8:02 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Fri, Jun 10, 2016 at 7:18 AM, Haravikk <swift-evolution@haravikk.me <mailto:swift-evolution@haravikk.me>> wrote:

* The word "where" does not consistently imply `break` or `continue`. In current Swift, `where` implies `break` in the context of a `while` loop and `continue` in the context of a `for` loop. Some users intuitively guess the correct meaning in each context, while others guess the wrong meaning. Therefore, the only way to learn for sure what `where` means in any context is to read the rulebook. That, by definition, means that this is unintuitive.

This is an argument for renaming the where keyword on for loops to be more clear, or to somehow integrate continue/break to be more explicit about what the developer intends for it to do.

Sure: I conclude that the keyword should be *either* removed *or* reformed; both outcomes could address the issue.

This is my stance as well and I reserve the right to flit between both choices until we've fully talked it through.

One more data point.

In the standard library there are just under 950 uses of "for in loops". There are 3 uses of "for in while" :

private/StdlibUnittest/StdlibUnittest.swift.gyb: for j in instances.indices where i != j {
public/core/Algorithm.swift: for value in rest where value < minValue {
public/core/Algorithm.swift: for value in rest where value >= maxValue {

-- Erica

And to follow-up to myself once again, I went to my "Cool 3rd Party Swift Repos" folder and did the same search. Among the 15 repos in that folder, a joint search returned about 650 hits on for-in (again with some false positives) and not a single for-in-while use.

-- E

Ā·Ā·Ā·

On Jun 10, 2016, at 9:24 AM, Erica Sadun <erica@ericasadun.com> wrote:

On Jun 10, 2016, at 9:22 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Jun 10, 2016, at 8:02 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Fri, Jun 10, 2016 at 7:18 AM, Haravikk <swift-evolution@haravikk.me <mailto:swift-evolution@haravikk.me>> wrote:

* The word "where" does not consistently imply `break` or `continue`. In current Swift, `where` implies `break` in the context of a `while` loop and `continue` in the context of a `for` loop. Some users intuitively guess the correct meaning in each context, while others guess the wrong meaning. Therefore, the only way to learn for sure what `where` means in any context is to read the rulebook. That, by definition, means that this is unintuitive.

This is an argument for renaming the where keyword on for loops to be more clear, or to somehow integrate continue/break to be more explicit about what the developer intends for it to do.

Sure: I conclude that the keyword should be *either* removed *or* reformed; both outcomes could address the issue.

This is my stance as well and I reserve the right to flit between both choices until we've fully talked it through.

One more data point.

In the standard library there are just under 950 uses of "for in loops". There are 3 uses of "for in while" :

private/StdlibUnittest/StdlibUnittest.swift.gyb: for j in instances.indices where i != j {
public/core/Algorithm.swift: for value in rest where value < minValue {
public/core/Algorithm.swift: for value in rest where value >= maxValue {

-- Erica

Actually a slight correction to that. I forgot to add the space after "in" on the first search. It's just over 600 and 3. Among the 600 are a few false positives but not many.

-- E

For in where, not for in while. d'erp.

Ā·Ā·Ā·

On Jun 10, 2016, at 9:49 AM, Erica Sadun <erica@ericasadun.com> wrote:

On Jun 10, 2016, at 9:24 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

On Jun 10, 2016, at 9:22 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Jun 10, 2016, at 8:02 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Fri, Jun 10, 2016 at 7:18 AM, Haravikk <swift-evolution@haravikk.me <mailto:swift-evolution@haravikk.me>> wrote:

* The word "where" does not consistently imply `break` or `continue`. In current Swift, `where` implies `break` in the context of a `while` loop and `continue` in the context of a `for` loop. Some users intuitively guess the correct meaning in each context, while others guess the wrong meaning. Therefore, the only way to learn for sure what `where` means in any context is to read the rulebook. That, by definition, means that this is unintuitive.

This is an argument for renaming the where keyword on for loops to be more clear, or to somehow integrate continue/break to be more explicit about what the developer intends for it to do.

Sure: I conclude that the keyword should be *either* removed *or* reformed; both outcomes could address the issue.

This is my stance as well and I reserve the right to flit between both choices until we've fully talked it through.

One more data point.

In the standard library there are just under 950 uses of "for in loops". There are 3 uses of "for in while" :

private/StdlibUnittest/StdlibUnittest.swift.gyb: for j in instances.indices where i != j {
public/core/Algorithm.swift: for value in rest where value < minValue {
public/core/Algorithm.swift: for value in rest where value >= maxValue {

-- Erica

Actually a slight correction to that. I forgot to add the space after "in" on the first search. It's just over 600 and 3. Among the 600 are a few false positives but not many.

-- E

And to follow-up to myself once again, I went to my "Cool 3rd Party Swift Repos" folder and did the same search. Among the 15 repos in that folder, a joint search returned about 650 hits on for-in (again with some false positives) and not a single for-in-while use.

-- E

The thought here is along the lines of what Chris said, quoted above, and repeated here: "The extended C family of language [...] is an extremely popular and widely used set[;] programmers move around and work in different languages, and [aligning to expectations arising from other C family languages] allows a non-expert in the language to understand what is going on." By contrast, the `where` clause violates that expectation and I do not see "overwhelmingly large advantages" for doing so.

I think you might be slightly misunderstanding Chris's point here. In the thread you quoted, somebody suggested fundamentally changing the very structure of the syntaxā€”the way blocks are marked outā€”to something completely different from C. Chris said that such a huge deviation from the C family would need "overwhelmingly large advantages" before they would accept it.

This is not the same situation. It is true that there's no similar feature in Cā€”mainly because C's loose typing allows you to use && insteadā€”but the `where` clause is a mere augmentation of C practice, not a complete break from it. It does not need to pass nearly so stringent a test.

Ā·Ā·Ā·

--
Brent Royal-Gordon
Architechies

And to follow-up to myself once again, I went to my "Cool 3rd Party Swift Repos" folder and did the same search. Among the 15 repos in that folder, a joint search returned about 650 hits on for-in (again with some false positives) and not a single for-in-while use.

Weird. My own Swift projects (not on Github :P) use ā€œwhereā€ all the time with for loops. I really like it and think it reads *and* writes far better as well as makes for nicer one-liners. In one project, by rough count, I have about 20 that use ā€œwhereā€ vs. 40 in that same project not using ā€œwhereā€.

In another smaller test project, there are only 10 for loops, but even so one still managed to use where.

Not a lot of data without looking at even more projects, I admit, but this seems to suggest that the usage of ā€œwhereā€ is going to be very developer-dependent. Perhaps thereā€™s some factor of prior background at work here? (Iā€™ve done a lot of SQL in another life, for example.)

I feel like ā€œwhereā€ is a more declarative construct and that we should be encouraging that way of thinking in general. When using it, it feels like ā€œmagicā€ for some reason - even though thereā€™s nothing special about it. It feels like Iā€™ve made the language work *for me* a little bit rather than me having to contort my solution to the will of the language. This may be highly subjective.

l8r
Sean

-1

* Swift is explicitly a C-family language. In most or all other C-family
languages, for loop statements allow specification of conditions for
exiting the loop but not for filtering. Therefore, Swift's use of `where`
is unprecedented and needs to be learned anew by every user of Swift.

When was this decided? I distinctly remember some bloke under Craig
Federighiā€™s hair saying that it was time to ā€œmove beyondā€ C and essentially
ditch legacy conventions which no longer make sense.

I think you misunderstood my argument here. I don't mean that we should
yoke ourselves to C conventions, and we should absolutely ditch C
convention when it doesn't make sense. The big-picture argument here is
that `where` doesn't pass the bar of correcting a C convention that no
longer makes sense.

FWIW, on the topic of syntax choices, here is what Chris Lattner had to say
on this list:

Kevin got it exa*c*tly right, but Iā€™d expand that last bit a bit to:

ā€œā€¦ pi*c*king the one that is most familiar to programmers in the extended
*C* *family* is a good idea.["]
The extended *C* *family* of language (whi*c*h in*c*ludes *C*, *C*++, Obj
*C*, but also *C*#, Java, Javas*c*ript, and more) is
an extremely popular and widely used set of languages that have a lot of
surfa*c*e-level similarity. I
donā€™t *c*laim to know the design rationale of all of these languages, but
I surmise that this is not an
a*c**c*ident: programmers move around and work in different languages,
and this allows a non-expert in the
language to understand what is going on. While there are things about *C*
that are really unfortunate IMO
(e.g. the de*c*larator/de*c*laration spe*c*ifier part of the grammar)
there is a lot of goodness in the basi
*c*operator set, fo*c*us on dot syntax, and more.
I do agree that there are some benefits to dit*c*hing bra*c*es and
relying on indentation instead, but there are
also downsides. Deviating from the *C* *family* in this respe*c*t would
have to provide **overwhelmingly** large
advantages for us to take su*c*h a plunge, and they simply donā€™t exist.

As I understand it, Swift is a new language with new conventions. It is
desirable to align as many of those as possible with existing conventions
so as to be easily learned, but if you limit Swift to other languages
conventions you deny it any identity. Did Python ask anybodyā€™s opinion
before dropping curly-braces? Did people learn whatever Perl is supposed to
be? Look at Cā€™s hieroglyphic for loops!

I don't think we disagree here.

Realistically, ā€œfor ā€¦ in ā€¦ whileā€ is not going to cause incredible
confusion. Removing it would cause a lot of frustration. You canā€™t on the
one hand say our users are comfortable with the axioms of Cā€™s hieroglyphic
loops, and on the other hand say ā€œfor x in y while" is confusing.

Again, as I said, once you've mastered something, by definition you find
it not confusing. Why should we doom x% of new users to writing a loop
incorrectly at least once when we don't have to?

Ah, but if youā€™re not ā€œdoomedā€ to failing once, how will you ever master
anything? Nobody knew how to write a C for-loop until someone showed them
(and even thenā€¦). Nobody is going to just open a REPL and start writing
code, with zero prior understanding of what Swift syntax looks like.

The thought here is along the lines of what Chris said, quoted above, and
repeated here: "The extended C family of language [...] is an extremely
popular and widely used set[;] programmers move around and work in
different languages, and [aligning to expectations arising from other C
family languages] allows a non-expert in the language to understand what is
going on." By contrast, the `where` clause violates that expectation and I
do not see "overwhelmingly large advantages" for doing so.

* The word "where" does not consistently imply `break` or `continue`. In
current Swift, `where` implies `break` in the context of a `while` loop and
`continue` in the context of a `for` loop. Some users intuitively guess the
correct meaning in each context, while others guess the wrong meaning.
Therefore, the only way to learn for sure what `where` means in any context
is to read the rulebook. That, by definition, means that this is
unintuitive.

I didnā€™t even know while loops supported ā€œwhereā€. I canā€™t even imagine
what that would look like, or how I would reason about one if I saw one. I
Googled around a little bit and couldnā€™t find any examples. If they exist,
sure, go ahead, get rid of them. Nobody will miss them.

Actually, we had a *huge* chain where there were definitely people who said
they would miss them, even though as you said it appears scarcely used and
not very well known. The pernicious problem with it was that it forced even
unrelated boolean assertions to be chained with `where`, as in:

while let x = iterator.next() where y < z { ... }

It definitely makes sense on ā€˜forā€™, though. Lots and lots of people will
miss that; itā€™s a pretty well-known feature.

(See Erica's statistics below.)

Also, after everything you said, itā€™s still not unintuitive. That is not

how languages work at all. Languages spoken by human beings are always
ambiguous to some extent, and we use context to determine which meaning is
correct:

(Quote from
Announcing SyntaxNet: The Worldā€™s Most Accurate Parser Goes Open Source ā€“ Google Research Blog
)

One of the main problems that makes parsing so challenging is that human
languages show remarkable levels of ambiguity. It is not uncommon for
moderate length sentences - say 20 or 30 words in length - to have
hundreds, thousands, or even tens of thousands of possible
syntactic structures. A natural language parser must somehow search through
all of these alternatives, and find the most plausible structure given
the context. As a very simple example, the sentence "Alice drove down the
street in her car" has at least two possible dependency parses:

The first corresponds to the (correct) interpretation where Alice is
driving in her car; the second corresponds to the (absurd, but
possible) interpretation where the street is located in her car. The
ambiguity arises because the preposition ā€œin" can either
modify drove or street; this example is an instance of what is
called prepositional phrase attachment ambiguity.

Even algebra is not completely unambiguous - you need to use BODMAS rules
to disambiguate potential meanings.
Itā€™s this context which I think youā€™re missing when zooming in at the word
ā€œwhereā€:

- The context that this is a variation of a ā€˜for x in yā€™ loop. We know
that it loops through every item in ā€˜y' and assigns it ā€˜xā€™. It is literally
Section 2 of the 'Swift Tour' - you learn how to assign a variable, and
then you learn about the ā€œfor x in yā€ loop. Everybody should recognise it.
- The context that ā€˜xā€™ is the subject, so ā€˜whereā€™ is clearly a condition
for x to fulfill
- The context that ā€˜whereā€™ occurs after ā€˜inā€™, so it follows the order in
which its written: ā€˜for every x in y, where such-and-such is true, do ā€¦ā€
- The ā€œfor x in yā€ loop is a data-driven loop. It doesnā€™t even have a loop
index. It is not like a C for loop and you shouldnā€™t expect to reason about
it that way.

* There are other ways to break from a loop or continue to the next
iteration without performance penalty. Nearly all of these serve more
general purposes than a `where` clause. Some of these (such as `if` or
`guard`) would already be familiar to a new user before they encounter
loops, assuming a typical order for learning a programming language. Many
of these (such as filtering methods on collections, or simply `if`) would
be familiar to a user of another C-family language. Therefore, the `where`
clause provides no independent utility, is not more discoverable than its
alternatives, and is not required for progressive disclosure of an
important facility to a learner (i.e. a simplified syntax for those who may
not be ready for the advanced concepts needed to use a more fully-featured
alternative).

You say the points in favour of removal are not handwavey, but Iā€™m still
not convinced. ā€œThere are other ways to go to where this shortcut goesā€ is
not reasoning. And Iā€™d definitely argue that it is more discoverable than
the ā€˜guardā€™ statement. The guard statement is stone-dead last at the end of
a massive ā€œControl-Flowā€ page. I would guess that most first-time readers
skip those topics for later.

You cannot say the same about `if`.

The point here is that this is not a slippery slope. If `where` offered
independent utility, then some confusion alone probably wouldn't be enough
to justify removal, though it may justify some consideration for change.
However, as the extensive discussion has shown, there is nothing `where`
can do that something else can't do better. I know you like it for style,
but that's not sufficient grounds for keeping something confusing, IMO.

Itā€™s more readable. It does that better.

Earlier in this thread and others, I gave my reasoning where I disagree
with this assertion about being more readable.

The tests also seem to show that (bizarrely) itā€™s also slightly faster
than the alternatives.

I don't believe there has been any demonstration that it's faster than
`guard` or `if`. I would be shocked if that were the case.

Ā·Ā·Ā·

On Fri, Jun 10, 2016 at 6:10 AM, Karl <razielim@gmail.com> wrote:

Karl

On 10 Jun 2016, at 08:25, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

On Fri, Jun 10, 2016 at 12:48 AM, Brandon Knope <bknope@me.com> wrote:

On Jun 10, 2016, at 1:08 AM, Xiaodi Wu via swift-evolution < >> swift-evolution@swift.org> wrote:

On Thu, Jun 9, 2016 at 9:45 PM, Dany St-Amant <dsa.mls@icloud.com> wrote:

Le 9 juin 2016 Ć  14:55, Xiaodi Wu via swift-evolution < >>> swift-evolution@swift.org> a Ć©crit :

There have been, in previous threads, several examples given where users
of Swift have found the behavior of `where` to be misleading and confusing.

Sorry Xiaodi, but beside you (on multiple instances), and recently
Erica, I have do not recall hearing that many voices saying that 'where' is
confusing.

Shawn Erickson wrote this to the list just yesterday:

"I support your position on the use of where and while/when being
confusing in the loop statement. I (and I know others) have for example
used where in a loop statement mistakenly thinking it would terminate the
loop early but of course learned that it basically filters what causes the
loop body to be executed. After the fact that made sense to me but it
didn't click at first."

Couldn't we find examples of anyone being confused at any syntax?
Especially with an unfamiliar construct in a new language.

If people find the new proposed syntax confusing, do we pull that too? At
what point do we stop?

That is why I favored (1) removal of the confusing syntax altogether; and
(2) this proposal, which involves aligning the confusing syntax with an
existing syntax. In short, no new syntax to get confused about.

Yes, there's was maybe even less voices stating that it is not confusing,

but which group is more vocal?

Maybe I have been recently corrupt by Solid SQL queries:
select * from PEOPLE_TABLE where AGE_FIELD = 100

Or by my (likely) broken English:
The places where I had the most fun

But, to me, where can only suggest some filtering (thus tag to a for ..
in .., continue if not matching).

I'm glad that you find it very clear. I do as well. That does not mean it
is clear to everyone.

I still have yet to see widespread confusion of this. A few people
learning swift here or there, but once they learn the syntax...do they
still find it confusing?

I expect some concrete data on stuff like this...especially with proposed

syntax changes.

Without concrete examples, what would stop one from coming in here and
waving their hands around to push *what they like* through?

Here's what's not handwavy:

Conclusion: the `where` clause is unprecedented, unintuitive, provides no
independent utility, is not more discoverable than alternatives, and is not
required for pedagogical reasons; however, it has been used incorrectly by
at least some users. Therefore, it is harmful and ought to be removed or
reformed.

I know there's a linguist on the list, maybe he could comment on whether

or not using 'where' as a filter is proper or an abomination.

I do not think that because something is confusing to some, or at first,
that it warrant removal from the language.

It is a very bad sign if something is confusing at first, especially to a
significant proportion of users. It's true by definition that once you have
mastered something you are no longer confused by it.

Again, where is this significant proportion of users? I don't mean to
hound you on this, but I am genuinely curious where this is all coming from.

We were talking about the hypothetical something here and what the bar
should be for removal from the language. My response is that being
confusing at first sight *is* a legitimate consideration for removal from
the language. If something turns out to be a confusing way to describe a
straightforward concept, then the more widespread the confusion, the more
urgent its removal.

The burden of evidence is on the proposers of these ideas.

As has been stated on this list, education is a valid and important
consideration for Swift. If something is confusing rather than difficult
(and the *concept* of filtering a list is not at all a difficult concept),
and if the same underlying concept can already be invoked in alternative
and equivalent ways that are not confusing, then it's a no-brainer that the
confusing thing is harmful to the language and should be removed on that
basis alone.

What is clear to one person may be confusing to another. There is no
perfect syntax that will not make it confusing for some users.

----

I really think it is important to come armed with more information with
these proposals. It's easy to say a significant proportion of people are
confused but it would make me much more comfortable to see this data to
back it up.

What if we are spinning our wheels for no reason on a feature that *most*
don't find confusing? What if we make a bigger proportion of those who did
understand it more confused now?

Brandon

By analogy, Chinese and Japanese share difficult writing systems. Yet
many people use those languages daily without difficulty. Does that mean
there's not a problem? Far from it: in fact, you'll find that many
intelligent people have devoted their life's work to mitigating the issue.
Both Chinese and Japanese underwent a round of simplification in the 20th
century. Think about it: real languages used for daily life by a
significant fraction of the world's population were revamped for the
purpose of increasing accessibility to new learners.

The by-value/by-reference is well define, but can be confusing at first.

Same goes for eager/lazy processing, or escaping vs non-escaping closure,
or even the difference between closure and function. But no one suggest to
remove them.

Value types vs. reference types is a concept (and a moderately advanced
one), eager vs. lazy processing is a concept (and a moderately advanced
one), and closures are a concept (and definitely an advanced one).

Filtering a collection is a concept as well, and no one is suggesting its
removal. We are proposing to simplify and rationalize the syntax by which
filtering is invoked. If there were a way to dramatically simplify the
syntax surrounding value types and reference types so as to diminish
confusion, you can absolutely guarantee that there would be proposals to
change the syntax. If I could think of one tomorrow, you'd see a thread
tomorrow about it. I don't think I'm that smart though.

Dany

In fact, the first of these proposals began with a question: how does
one write arbitrary Boolean assertions after a let binding? The answer (use
`where`) was found to be misleading and confusing.

I think you're being unfair to say that these proposals have no purpose
other than an academic consistency.
On Thu, Jun 9, 2016 at 13:29 Jon Shier via swift-evolution < >>> swift-evolution@swift.org> wrote:

        As time goes on, Iā€™m feeling more and more that these
consistency proposals are sorely misguided. Frankly, unless the syntax is
confusing or misleading, even once the developer has learned the guiding
principles of Swift, consistency is not a good argument for change. This
proposal is the perfect example of this. No one will find the use of
ā€œwhereā€ in loops confusing, aside from those who will wonder why it was
removed from if statements. There is no misleading behavior or confusing
syntax here. This is just consistency for consistencyā€™s sake. Once this
proposal is done, then another will be made to remove ā€œwhereā€ from another
place in the language. Then another and another until itā€™s gone completely
and a very useful part of the language is removed in the name of
consistency. Which really just comes down to ā€œwhereā€ isnā€™t used here, so it
canā€™t be used there anymore. Itā€™s death by a thousand cuts.

Jon Shier

> On Jun 9, 2016, at 1:16 PM, Erica Sadun via swift-evolution < >>>> swift-evolution@swift.org> wrote:
>
>
>> On Jun 9, 2016, at 11:11 AM, Charlie Monroe < >>>> charlie@charliemonroe.net> wrote:
>> See my latest post - included results with -Ofast. But still, using
filter and lazy.filter is 10+% slower, which were the suggested
alternatives to `where`.
>>
>>
>
> I need to correct this misapprehension.
> My suggested alternative to where was and remains `guard`.
>
> -- E
>
> _______________________________________________
> 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

_______________________________________________
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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

>
> * The word "where" does not consistently imply `break` or `continue`. In
current Swift, `where` implies `break` in the context of a `while` loop and
`continue` in the context of a `for` loop. Some users intuitively guess the
correct meaning in each context, while others guess the wrong meaning.
Therefore, the only way to learn for sure what `where` means in any context
is to read the rulebook. That, by definition, means that this is
unintuitive.

An example here would have help... I had trouble visualizing the 'where'
with 'while'. A quick example I was able to conjure is:

var array = [9,8,7,6,5,4,3,2,1]
while let x = are.popLast() where x < 5 { print(x) }
print(array)

What? 'array' is not empty at the end. I admit, I was surprised by the
result at first. The confusion here is not that 'where' in 'for' behave
like 'continue' and 'where' in 'while' act like a 'break', as the later
doesn't conceptually exist. The later concept is using 'where' as a
conditional binding in a 'while' causes a failure of the bind and thus a
'break' out of the loop. With the acceptance of the revised SE-0099, the
'while' can no longer appear to be using 'where', thus removing this
confusion.

I'm relieved that it's been addressed. There was no small amount of
contention that `where` in `while` loops was stylistically delightful and
ought to remain, but I think you see why at least on first sight it is
rather alarming.

Ā·Ā·Ā·

On Fri, Jun 10, 2016 at 7:45 AM, Dany St-Amant <dsa.mls@icloud.com> wrote:

> Le 10 juin 2016 Ć  02:25, Xiaodi Wu <xiaodi.wu@gmail.com> a Ć©crit :

Dany

> And to follow-up to myself once again, I went to my "Cool 3rd Party
Swift Repos" folder and did the same search. Among the 15 repos in that
folder, a joint search returned about 650 hits on for-in (again with some
false positives) and not a single for-in-while use.

Weird. My own Swift projects (not on Github :P) use ā€œwhereā€ all the time
with for loops. I really like it and think it reads *and* writes far better
as well as makes for nicer one-liners. In one project, by rough count, I
have about 20 that use ā€œwhereā€ vs. 40 in that same project not using
ā€œwhereā€.

In another smaller test project, there are only 10 for loops, but even so
one still managed to use where.

Not a lot of data without looking at even more projects, I admit, but this
seems to suggest that the usage of ā€œwhereā€ is going to be very
developer-dependent. Perhaps thereā€™s some factor of prior background at
work here? (Iā€™ve done a lot of SQL in another life, for example.)

That is worrying if true, because it suggests that it's enabling 'dialects'
of Swift, an explicit anti-goal of the language.

Ā·Ā·Ā·

On Fri, Jun 10, 2016 at 11:23 AM, Sean Heber via swift-evolution < swift-evolution@swift.org> wrote:

I feel like ā€œwhereā€ is a more declarative construct and that we should be
encouraging that way of thinking in general. When using it, it feels like
ā€œmagicā€ for some reason - even though thereā€™s nothing special about it. It
feels like Iā€™ve made the language work *for me* a little bit rather than me
having to contort my solution to the will of the language. This may be
highly subjective.

l8r
Sean

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I think this idea--if you don't like it, then you don't have to use it--is
indicative of a key worry here: it's inessential to the language and
promotes dialects wherein certain people use it and others wherein they
don't. This is an anti-goal.

Iā€™m not sold on the argument that there canā€™t be areas of the language
that are inessential. Yes, we could build a language with extremely limited
control structures (conditional branch and goto), and they would be used by
100% of the users. Beyond that, however, everything is ā€œinessentialā€.
Adding room for elegance and expressiveness, even when perhaps initially
seldom used, doesnā€™t seem wrong: this language is still young, after all.
Letā€™s not shoot decide a feature isnā€™t used before we even give it a chance
to be recognized as a feature.

I do agree with the premise here. There is absolutely something to be said
for elegance and expressiveness. Moreover, expressiveness goes hand in hand
with facilitating correctness. We could reduce everything to goto's and
conditional branches, but correctness suffers greatly and readability of
the code would be abysmal--and I think I'll find agreement that it's a
solidly grounded opinion.

So "inessential" alone is not a good sole criterion--I agree. But it is one
of several prongs here: `where` is not only inessential, I argue that it
lacks expressiveness (in that what is enabled by it can be expressed
equally or even more cogently with `guard`, a more general and more
expressive syntax overall), and it detracts from rather than helps with
writing correct code, because we hear attestations that its use has gone
awry (and the going awry happens at runtime!). So in essence, I would be
content with inessential but expressive solutions, but here I argue that
`where` is neither essential nor expressive.

Elegance is in the eye of the beholder, but FWIW I do not find `where`
elegant; it irks me greatly from an aesthetic point of view just as it
delights others. I see no point in debating personal taste, however.

Ā·Ā·Ā·

On Fri, Jun 10, 2016 at 12:47 PM, James Berry <jberry@rogueorbit.com> wrote:

On Jun 10, 2016, at 10:17 AM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

I would argue that at least one reason the where clause is little used on
for-in loops in code in the field is that itā€™s barely documented. I donā€™t
see any reference to it, or example of it, in the Swift 2.2 language guide.
One has to read the grammar for the for statement in the more technical
Language Reference in order to find it, and even there itā€™s behavior is not
defined that I can see.

Using or not using a feature does not create a dialect of a language.

On Fri, Jun 10, 2016 at 12:10 let var go <letvargo@gmail.com> wrote:

Leave it in!

It's a great little tool. I don't use it very often, but when I do it is
because I've decided that in the context of that piece of code it does
exactly what I want it to do with the maximum amount of clarity.

If you don't like it, then don't use it, but I can't see how it detracts
from the language at all.

The *only* argument that I have heard for removing it is that some people
don't immediately intuit how to use it. I didn't have any trouble with it
at all. It follows one of the most basic programming patterns ever: "For
all x in X, if predicate P is true, do something." The use of the keyword
"where" makes perfect sense in that context, and when I read it out loud,
it sounds natural: "For all x in X where P, do something." That is an
elegant, succinct, and clear way of stating exactly what I want my program
to do.

I don't doubt that it has caused some confusion for some people, but I'm
not sold that that is a good enough reason to get rid of it. It seems
strange to get rid of a tool because not everyone understands how to use it
immediately, without ever having to ask a single question. As long as its
not a dangerous tool (and it isn't), then keep it in the workshop for those
times when it comes in handy. And even if there is some initial confusion,
it doesn't sound like it lasted that long. It's more like, "Does this work
like X, or does this work like Y? Let's see...oh, it works like X. Ok."
That's the entire learning curve...about 5 seconds of curiosity followed by
the blissful feeling of resolution.

On Fri, Jun 10, 2016 at 9:32 AM Xiaodi Wu via swift-evolution < >> swift-evolution@swift.org> wrote:

On Fri, Jun 10, 2016 at 11:23 AM, Sean Heber via swift-evolution < >>> swift-evolution@swift.org> wrote:

> And to follow-up to myself once again, I went to my "Cool 3rd Party
Swift Repos" folder and did the same search. Among the 15 repos in that
folder, a joint search returned about 650 hits on for-in (again with some
false positives) and not a single for-in-while use.

Weird. My own Swift projects (not on Github :P) use ā€œwhereā€ all the
time with for loops. I really like it and think it reads *and* writes far
better as well as makes for nicer one-liners. In one project, by rough
count, I have about 20 that use ā€œwhereā€ vs. 40 in that same project not
using ā€œwhereā€.

In another smaller test project, there are only 10 for loops, but even
so one still managed to use where.

Not a lot of data without looking at even more projects, I admit, but
this seems to suggest that the usage of ā€œwhereā€ is going to be very
developer-dependent. Perhaps thereā€™s some factor of prior background at
work here? (Iā€™ve done a lot of SQL in another life, for example.)

That is worrying if true, because it suggests that it's enabling
'dialects' of Swift, an explicit anti-goal of the language.

I feel like ā€œwhereā€ is a more declarative construct and that we should
be encouraging that way of thinking in general. When using it, it feels
like ā€œmagicā€ for some reason - even though thereā€™s nothing special about
it. It feels like Iā€™ve made the language work *for me* a little bit rather
than me having to contort my solution to the will of the language. This may
be highly subjective.

l8r
Sean

_______________________________________________
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

_______________________________________________

swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

* The word "where" does not consistently imply `break` or
  `continue`. In current Swift, `where` implies `break` in the
  context of a `while` loop and `continue` in the context of a
  `for` loop. Some users intuitively guess the correct meaning in
  each context, while others guess the wrong meaning. Therefore,
  the only way to learn for sure what `where` means in any
  context is to read the rulebook. That, by definition, means
  that this is unintuitive.

This is an argument for renaming the where keyword on for loops to
be more clear, or to somehow integrate continue/break to be more
explicit about what the developer intends for it to do.

Sure: I conclude that the keyword should be *either* removed *or*
reformed; both outcomes could address the issue.

This is my stance as well and I reserve the right to flit between
both choices until we've fully talked it through.

One more data point.

In the standard library there are just under 950 uses of "for in
loops". There are 3 uses of "for in while" :

private/StdlibUnittest/StdlibUnittest.swift.gyb: for j in
instances.indices where i != j {
public/core/Algorithm.swift: for value in rest where value <
minValue {
public/core/Algorithm.swift: for value in rest where value >=
maxValue {

-- Erica

Actually a slight correction to that. I forgot to add the space after
"in" on the first search. It's just over 600 and 3. Among the 600 are
a few false positives but not many.

-- E

And to follow-up to myself once again, I went to my "Cool 3rd Party
Swift Repos" folder and did the same search. Among the 15 repos in
that folder, a joint search returned about 650 hits on for-in (again
with some false positives) and not a single for-in-while use.

I have access to 3 closed-source enterprise applications, iOS 9 and 100%
Swift 2.2. Each of them respectively have one "for in loop"; each one
makes use of a "where" clause.

Two of the applications are maintained/written by someone other than
myself. I wanted to audit them to see if those developers used "for in"
correctly or incorrectly; indeed they were all correctly used to filter
an Array. Though I cannot rule out they did not stumble into correct use
of the `where` clause.

More food for thought. Looking at the Git history I realized one of them
actually was refactored from something that looked like:

let a = [3, 1, 2].sort()
a.filter({ $0 <= 2 }).forEach({ print($0) })

to

let a = [3, 1, 2].sort()
for i in a where i <= 2 { print(i) }

I'm reasonably confident when I say the developers of this code have
never heard of swift-evolution let alone participated in it.

Obviously this is anecdotal evidence. It could be that `where` clause
is "easy to understand" _or_ equally likely that our hiring process
does a great job of selecting a heterogenous population of developers
with certain backgrounds that lead to similar code when faced with
similar problems.

You know what strikes me about this whole argument? "[This argument] is
like a rocking chair: it gives [us] something to do but [does not get
us] anywhere". - Someone Else

If this is an example of the pressing/priority issues facing the Swift
language today then I say lets all take a long weekend to bask in the
glow of this momentous occasion. Then meet back here in 2 years.

Change it or do not change it. I do not imagine it matters either way in
5 years. That having been said though I do think this argument, and
others similar to it, are important because I think they run deeper than
the syntax. I think they speak to the ethos of this community. With that
I think we should think long and hard about this process and what it
speaks to in terms of precedence and our collective priorities.

Ā·Ā·Ā·

On Fri, Jun 10, 2016, at 11:49 AM, Erica Sadun via swift-evolution wrote:

On Jun 10, 2016, at 9:24 AM, Erica Sadun >> <erica@ericasadun.com> wrote:

On Jun 10, 2016, at 9:22 AM, Erica Sadun via swift-evolution <swift- >>> evolution@swift.org> wrote:

On Jun 10, 2016, at 8:02 AM, Xiaodi Wu via swift-evolution <swift- >>>> evolution@swift.org> wrote:
On Fri, Jun 10, 2016 at 7:18 AM, Haravikk <swift- >>>> evolution@haravikk.me> wrote:

-- E
_________________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

> The thought here is along the lines of what Chris said, quoted above,
and repeated here: "The extended C family of language [...] is an extremely
popular and widely used set[;] programmers move around and work in
different languages, and [aligning to expectations arising from other C
family languages] allows a non-expert in the language to understand what is
going on." By contrast, the `where` clause violates that expectation and I
do not see "overwhelmingly large advantages" for doing so.

I think you might be slightly misunderstanding Chris's point here. In the
thread you quoted, somebody suggested fundamentally changing the very
structure of the syntaxā€”the way blocks are marked outā€”to something
completely different from C. Chris said that such a huge deviation from the
C family would need "overwhelmingly large advantages" before they would
accept it.

This is not the same situation. It is true that there's no similar feature
in Cā€”mainly because C's loose typing allows you to use && insteadā€”but the
`where` clause is a mere augmentation of C practice, not a complete break
from it. It does not need to pass nearly so stringent a test.

Agreed. The test here probably shouldn't be nearly so stringent. But as a
component of grammar (vs. stdlib API), and since it touches looping (vs. a
more advanced concept such as closures), I'd argue that the bar is still
somewhat more elevated than other language features debated here.

Ā·Ā·Ā·

On Fri, Jun 10, 2016 at 12:51 PM, Brent Royal-Gordon <brent@architechies.com > wrote:

--
Brent Royal-Gordon
Architechies

@Xiaodi Wu a couple of times you've said things were "explicit"
this or that.

* Swift is explicitly a C-family language. In most or all other C-
family languages, for loop statements allow specification of
conditions for exiting the loop but not for filtering. Therefore,
Swift's use of `where` is unprecedented and needs to be learned anew
by every user of Swift.

That is worrying if true, because it suggests that it's enabling
'dialects' of Swift, an explicit anti-goal of the language

Though I've never read either of these before as being goals (or for
that matter anti-goals). Perhaps I'm looking in the wrong places though.
Can you please share these with me?

In trying to track that information down I read over
Swift.org - About Swift trying to find if I could glean any information
about some guiding principles. When I stumbled upon this and wondered if
anyone else would find it illuminating.

From the "Features" section:

Fast and concise iteration over a range or collection

Does this proposal enhance that feature? Does this proposal weaken
that feature?

I've thought about that for a little bit and I'm pretty sure that
removing `where` from for in certainly does not enhance that feature

If I understand everything this all started because `if` can no longer
have `where`. Following that and basing it completely on the example in
this proposal
(removingwhere.md Ā· GitHub)
it seems to me that the behavior of the `where` clause of the `while`
was analogous to the now removed `if` behavior.

Therefore, if we are going to remove something lets remove the `where`
clause from `while`. As is already correctly pointed out in the
"confusion of use" section the outlier behavior was `for in`. We
deprecated the `if` behavior because of [fill in the blank], forgive me
I never read the arguments, if `while` works the same way why does it
not logically follow that its `where` clause also be deprecated.

With that as far as I'm concerned this proposal is just requesting the
retirement of the `where` clause on the wrong loop structure. Of course
more examples could change my mind.

Ā·Ā·Ā·

from my perspective.

+1 to Haravikk's opinion, my thoughts exactly the same.

Ā·Ā·Ā·

On 10.06.2016 15:18, Haravikk via swift-evolution wrote:

On 10 Jun 2016, at 07:25, Xiaodi Wu via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
* Swift is explicitly a C-family language. In most or all other C-family
languages, for loop statements allow specification of conditions for
exiting the loop but not for filtering. Therefore, Swift's use of `where`
is unprecedented and needs to be learned anew by every user of Swift.

Swift may have some similarities with C, but the last thing anyone should
want is for it to be bound to C as a language. Besides, the purpose of a
for in loop is to iterate over elements in a sequence, so filtering is very
much a useful thing to do so itā€™s hardly unprecedented, and itā€™s also a
fairly common thing to want to do.

* The word "where" does not consistently imply `break` or `continue`. In
current Swift, `where` implies `break` in the context of a `while` loop
and `continue` in the context of a `for` loop. Some users intuitively
guess the correct meaning in each context, while others guess the wrong
meaning. Therefore, the only way to learn for sure what `where` means in
any context is to read the rulebook. That, by definition, means that this
is unintuitive.

This is an argument for renaming the where keyword on for loops to be more
clear, or to somehow integrate continue/break to be more explicit about
what the developer intends for it to do.

* There are other ways to break from a loop or continue to the next
iteration without performance penalty. Nearly all of these serve more
general purposes than a `where` clause.

This isnā€™t really an argument against the where clause; the where clause is
useful for common, simple cases, so itā€™s not surprising if more
complex/unusual cases canā€™t (or canā€™t easily) be handled by it. This is for
the simple cases where this isnā€™t an issue.

Some of these (such as `if` or `guard`) would already be familiar to a
new user before they encounter loops, assuming a typical order for
learning a programming language. Many of these (such as filtering methods
on collections, or simply `if`) would be familiar to a user of another
C-family language. Therefore, the `where` clause provides no independent
utility, is not more discoverable than its alternatives, and is not
required for progressive disclosure of an important facility to a learner
(i.e. a simplified syntax for those who may not be ready for the advanced
concepts needed to use a more fully-featured alternative).

Simplification isnā€™t just for the new users; all you need to know with
where is that itā€™s a shorthand for guard X else { continue }, for many
people this is intuitive enough, but if there are enough for whom it isnā€™t
then again thatā€™s an argument to tweak it to be more clear about what it
does, rather than remove it entirely.

The independent utility that it offers is being able to avoid if/guard
boilerplate at the start of your loop, but instead putting it on the same
line; in simple cases this can be nice and neat.

it has been used incorrectly by at least some users.

Every feature in every language "has been used incorrectly by at least some
users", should we just drop all programming languages? Itā€™s not as if users
canā€™t make mistakes while using an inline if/guard condition. Again, this
an argument that the meaning isnā€™t implicit enough, which is just as well
served by tweaking the syntax than removing it.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Leave it in!

It's a great little tool. I don't use it very often, but when I do it is
because I've decided that in the context of that piece of code it does
exactly what I want it to do with the maximum amount of clarity.

If you don't like it, then don't use it, but I can't see how it detracts
from the language at all.

The *only* argument that I have heard for removing it is that some people
don't immediately intuit how to use it. I didn't have any trouble with it
at all. It follows one of the most basic programming patterns ever: "For
all x in X, if predicate P is true, do something." The use of the keyword
"where" makes perfect sense in that context, and when I read it out loud,
it sounds natural: "For all x in X where P, do something." That is an
elegant, succinct, and clear way of stating exactly what I want my program
to do.

I don't doubt that it has caused some confusion for some people, but I'm
not sold that that is a good enough reason to get rid of it. It seems
strange to get rid of a tool because not everyone understands how to use it
immediately, without ever having to ask a single question. As long as its
not a dangerous tool (and it isn't), then keep it in the workshop for those
times when it comes in handy. And even if there is some initial confusion,
it doesn't sound like it lasted that long. It's more like, "Does this work
like X, or does this work like Y? Let's see...oh, it works like X. Ok."
That's the entire learning curve...about 5 seconds of curiosity followed by
the blissful feeling of resolution.

Ā·Ā·Ā·

On Fri, Jun 10, 2016 at 9:32 AM Xiaodi Wu via swift-evolution < swift-evolution@swift.org> wrote:

On Fri, Jun 10, 2016 at 11:23 AM, Sean Heber via swift-evolution < > swift-evolution@swift.org> wrote:

> And to follow-up to myself once again, I went to my "Cool 3rd Party
Swift Repos" folder and did the same search. Among the 15 repos in that
folder, a joint search returned about 650 hits on for-in (again with some
false positives) and not a single for-in-while use.

Weird. My own Swift projects (not on Github :P) use ā€œwhereā€ all the time
with for loops. I really like it and think it reads *and* writes far better
as well as makes for nicer one-liners. In one project, by rough count, I
have about 20 that use ā€œwhereā€ vs. 40 in that same project not using
ā€œwhereā€.

In another smaller test project, there are only 10 for loops, but even so
one still managed to use where.

Not a lot of data without looking at even more projects, I admit, but
this seems to suggest that the usage of ā€œwhereā€ is going to be very
developer-dependent. Perhaps thereā€™s some factor of prior background at
work here? (Iā€™ve done a lot of SQL in another life, for example.)

That is worrying if true, because it suggests that it's enabling
'dialects' of Swift, an explicit anti-goal of the language.

I feel like ā€œwhereā€ is a more declarative construct and that we should be
encouraging that way of thinking in general. When using it, it feels like
ā€œmagicā€ for some reason - even though thereā€™s nothing special about it. It
feels like Iā€™ve made the language work *for me* a little bit rather than me
having to contort my solution to the will of the language. This may be
highly subjective.

l8r
Sean

_______________________________________________
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

This is useful information.

I disagree that this is silly as a priority. IMO, this is something that
really needs to be tackled (if ever) in conjunction with Swift 3. Past this
point, the ship will have sailed in terms of churn in fundamental syntax.

We want to leave the language with a thoughtfully designed grammar that
will stand the test of time. Two of the most impressive elements of the
Swift ethos (for me) have been an attention to the needs of learners and a
determination that as much as possible we are designing One Swift and not
many dialects.

If a syntax for expressing a straightforward feature presents a speed bump
on the learning curve, I think it absolutely behooves us to think carefully
about its persistence, especially at this juncture where something can be
done about it. It may seem trivial to the experienced user, and probably
any person who finds their way to this list is unaffected by the learning
curve and long ago forgot what it was like to learn programming for the
first time, but one of those things I was so impressed by upon joining this
community was its attentiveness to fostering those that will come after.

So yes, if we do this right, in five years' time no one will remember this
discussion. The result of it will hopefully be a more thoughtful syntax
that fits with initial user expectation.

Ā·Ā·Ā·

On Fri, Jun 10, 2016 at 12:13 Ryan Lovelett via swift-evolution < swift-evolution@swift.org> wrote:

On Fri, Jun 10, 2016, at 11:49 AM, Erica Sadun via swift-evolution wrote:

On Jun 10, 2016, at 9:24 AM, Erica Sadun <erica@ericasadun.com> wrote:

On Jun 10, 2016, at 9:22 AM, Erica Sadun via swift-evolution < > swift-evolution@swift.org> wrote:

On Jun 10, 2016, at 8:02 AM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

On Fri, Jun 10, 2016 at 7:18 AM, Haravikk <swift-evolution@haravikk.me> > wrote:

* The word "where" does not consistently imply `break` or `continue`. In
current Swift, `where` implies `break` in the context of a `while` loop and
`continue` in the context of a `for` loop. Some users intuitively guess the
correct meaning in each context, while others guess the wrong meaning.
Therefore, the only way to learn for sure what `where` means in any context
is to read the rulebook. That, by definition, means that this is
unintuitive.

This is an argument for renaming the where keyword on for loops to be more
clear, or to somehow integrate continue/break to be more explicit about
what the developer intends for it to do.

Sure: I conclude that the keyword should be *either* removed *or*
reformed; both outcomes could address the issue.

This is my stance as well and I reserve the right to flit between both
choices until we've fully talked it through.

One more data point.

In the standard library there are just under 950 uses of "for in loops".
There are 3 uses of "for in while" :

private/StdlibUnittest/StdlibUnittest.swift.gyb: for j in
instances.indices where i != j {
public/core/Algorithm.swift: for value in rest where value < minValue {
public/core/Algorithm.swift: for value in rest where value >= maxValue {

-- Erica

Actually a slight correction to that. I forgot to add the space after "in"
on the first search. It's just over 600 and 3. Among the 600 are a few
false positives but not many.

-- E

And to follow-up to myself once again, I went to my "Cool 3rd Party Swift
Repos" folder and did the same search. Among the 15 repos in that folder, a
joint search returned about 650 hits on for-in (again with some false
positives) and not a single for-in-while use.

I have access to 3 closed-source enterprise applications, iOS 9 and 100%
Swift 2.2. Each of them respectively have one "for in loop"; each one makes
use of a "where" clause.

Two of the applications are maintained/written by someone other than
myself. I wanted to audit them to see if those developers used "for in"
correctly or incorrectly; indeed they were all correctly used to filter an
Array. Though I cannot rule out they did not stumble into correct use of
the `where` clause.

More food for thought. Looking at the Git history I realized one of them
actually was refactored from something that looked like:

let a = [3, 1, 2].sort()
a.filter({ $0 <= 2 }).forEach({ print($0) })

to

let a = [3, 1, 2].sort()
for i in a where i <= 2 { print(i) }

I'm reasonably confident when I say the developers of this code have never
heard of swift-evolution let alone participated in it.

Obviously this is anecdotal evidence. It could be that `where` clause is
"easy to understand" _or_ equally likely that our hiring process does a
great job of selecting a heterogenous population of developers with certain
backgrounds that lead to similar code when faced with similar problems.

You know what strikes me about this whole argument? "[This argument] is
like a rocking chair: it gives [us] something to do but [does not get us]
anywhere". - Someone Else

If this is an example of the pressing/priority issues facing the Swift
language today then I say lets all take a long weekend to bask in the glow
of this momentous occasion. Then meet back here in 2 years.

Change it or do not change it. I do not imagine it matters either way in 5
years. That having been said though I do think this argument, and others
similar to it, are important because I think they run deeper than the
syntax. I think they speak to the ethos of this community. With that I
think we should think long and hard about this process and what it speaks
to in terms of precedence and our collective priorities.

-- E
*_______________________________________________*
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

If the litmus test is whether using something can go awry and can go awry at runtime then you are going to have to chop off a lot of parts of most languages. Also, some programmers do not mind not being protected from themselves and trade that for extra freedom... which is not a bad thing in and of itself. In the end the question is an old one indeed, where do you draw the line between safety and freedom... as corny as it sounds. There are people on both sides.

I do not want a swift compiler flag that takes my idea and gets a team of contractors to build it... to take it to a ridiculous extreme :).

Ā·Ā·Ā·

Sent from my iPhone

On 10 Jun 2016, at 19:10, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

On Fri, Jun 10, 2016 at 12:47 PM, James Berry <jberry@rogueorbit.com> wrote:

On Jun 10, 2016, at 10:17 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

I think this idea--if you don't like it, then you don't have to use it--is indicative of a key worry here: it's inessential to the language and promotes dialects wherein certain people use it and others wherein they don't. This is an anti-goal.

Iā€™m not sold on the argument that there canā€™t be areas of the language that are inessential. Yes, we could build a language with extremely limited control structures (conditional branch and goto), and they would be used by 100% of the users. Beyond that, however, everything is ā€œinessentialā€. Adding room for elegance and expressiveness, even when perhaps initially seldom used, doesnā€™t seem wrong: this language is still young, after all. Letā€™s not shoot decide a feature isnā€™t used before we even give it a chance to be recognized as a feature.

I do agree with the premise here. There is absolutely something to be said for elegance and expressiveness. Moreover, expressiveness goes hand in hand with facilitating correctness. We could reduce everything to goto's and conditional branches, but correctness suffers greatly and readability of the code would be abysmal--and I think I'll find agreement that it's a solidly grounded opinion.

So "inessential" alone is not a good sole criterion--I agree. But it is one of several prongs here: `where` is not only inessential, I argue that it lacks expressiveness (in that what is enabled by it can be expressed equally or even more cogently with `guard`, a more general and more expressive syntax overall), and it detracts from rather than helps with writing correct code, because we hear attestations that its use has gone awry (and the going awry happens at runtime!). So in essence, I would be content with inessential but expressive solutions, but here I argue that `where` is neither essential nor expressive.

Elegance is in the eye of the beholder, but FWIW I do not find `where` elegant; it irks me greatly from an aesthetic point of view just as it delights others. I see no point in debating personal taste, however.

I would argue that at least one reason the where clause is little used on for-in loops in code in the field is that itā€™s barely documented. I donā€™t see any reference to it, or example of it, in the Swift 2.2 language guide. One has to read the grammar for the for statement in the more technical Language Reference in order to find it, and even there itā€™s behavior is not defined that I can see.

Using or not using a feature does not create a dialect of a language.

On Fri, Jun 10, 2016 at 12:10 let var go <letvargo@gmail.com> wrote:
Leave it in!

It's a great little tool. I don't use it very often, but when I do it is because I've decided that in the context of that piece of code it does exactly what I want it to do with the maximum amount of clarity.

If you don't like it, then don't use it, but I can't see how it detracts from the language at all.

The *only* argument that I have heard for removing it is that some people don't immediately intuit how to use it. I didn't have any trouble with it at all. It follows one of the most basic programming patterns ever: "For all x in X, if predicate P is true, do something." The use of the keyword "where" makes perfect sense in that context, and when I read it out loud, it sounds natural: "For all x in X where P, do something." That is an elegant, succinct, and clear way of stating exactly what I want my program to do.

I don't doubt that it has caused some confusion for some people, but I'm not sold that that is a good enough reason to get rid of it. It seems strange to get rid of a tool because not everyone understands how to use it immediately, without ever having to ask a single question. As long as its not a dangerous tool (and it isn't), then keep it in the workshop for those times when it comes in handy. And even if there is some initial confusion, it doesn't sound like it lasted that long. It's more like, "Does this work like X, or does this work like Y? Let's see...oh, it works like X. Ok." That's the entire learning curve...about 5 seconds of curiosity followed by the blissful feeling of resolution.

On Fri, Jun 10, 2016 at 9:32 AM Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

On Fri, Jun 10, 2016 at 11:23 AM, Sean Heber via swift-evolution <swift-evolution@swift.org> wrote:
> And to follow-up to myself once again, I went to my "Cool 3rd Party Swift Repos" folder and did the same search. Among the 15 repos in that folder, a joint search returned about 650 hits on for-in (again with some false positives) and not a single for-in-while use.

Weird. My own Swift projects (not on Github :P) use ā€œwhereā€ all the time with for loops. I really like it and think it reads *and* writes far better as well as makes for nicer one-liners. In one project, by rough count, I have about 20 that use ā€œwhereā€ vs. 40 in that same project not using ā€œwhereā€.

In another smaller test project, there are only 10 for loops, but even so one still managed to use where.

Not a lot of data without looking at even more projects, I admit, but this seems to suggest that the usage of ā€œwhereā€ is going to be very developer-dependent. Perhaps thereā€™s some factor of prior background at work here? (Iā€™ve done a lot of SQL in another life, for example.)

That is worrying if true, because it suggests that it's enabling 'dialects' of Swift, an explicit anti-goal of the language.

I feel like ā€œwhereā€ is a more declarative construct and that we should be encouraging that way of thinking in general. When using it, it feels like ā€œmagicā€ for some reason - even though thereā€™s nothing special about it. It feels like Iā€™ve made the language work *for me* a little bit rather than me having to contort my solution to the will of the language. This may be highly subjective.

l8r
Sean

_______________________________________________
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

_______________________________________________
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

In this case, I think it is hard to come with perfect example as beauty is in the eye of the beholder. Having the flexibility of using guard else { continue }, if not { continue } or where, is at some level a bit like choosing between:

if !(dataA == value || dataB == value) { }
if dataA != value && dataB != value { }
if dataA != value { if dataB != value { } }

All three are valid, and the baby pyramid of doom version may even be the right option depending on how you think the code will evolve.

Back to the where vs guard/if not continue, I see the former as "I want/like" and the laters as "I don't want/like".

for book in books where book.language == .French
{
    guard book.readCount == 0 else { continue }
    if book.originalLanguage == .English { continue } // should read the original
    // My apologies to translators who might feel offended.
}

One could put all the conditions as a single where, as a multiple guard, as multiple if, and as a single guard or if, but I think that my keyword choices better convey my message:

I want a book written in French
Protect me from what I have read
No translation from English for me
(Not that those are worst than others, but I can read the original... Apologies again to translator)

Dany

Ā·Ā·Ā·

Le 10 juin 2016 Ć  13:59, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> a Ć©crit :

But most importantly (and this is really the kicker for me) there are times when the "where" syntax provides the maximum amount of clarity in the context of my code, and I don't want to lose that expressive power.

This is the key and salient point here. Would you be able to share some examples where the `where` syntax provides a clear win in clarity? That would definitely be a huge pro, if it can be used to solve issues in expressiveness much like `guard` allowed elimination of the pyramid of doom.

Youā€™ve argued this several times, but I think the code speaks well enough for itself:

  for eachValue in theValues where eachValue.isOdd { ā€¦ }
  for eachValue in theValues {
    guard eachValue.isOdd else { continue }
  }

Not only is it an extra 15+ characters, itā€™s an extra line, so thereā€™s a definite saving right away.

The key issue is people misunderstanding that where is equivalent to continue and not break; this may be an issue of consistency, which will go away if ā€œwhereā€ is doomed to be removed from conditionals (which I believe includes while loops). Otherwise it seems like itā€™s based on a mistaken assumption that the for in loop wants to terminate rather than continue, but really its purpose is to visit as many matching elements of a sequence as possible (even with c-style for loops most for loops tend to be finite in a way that you can predict the number of loops before they run if you want to), whereas while loops can be considered designed to fail, at least thatā€™s how I was taught to use them. Of course both can be infinite and thereā€™s overlap in how theyā€™re used, but this is how I think about them, and thus what shapes conditions placed upon them.

Again though, if thereā€™ll only be one loop with a where clause like this then Iā€™m not sure itā€™s as much of an issue.

The obvious solution to clarity or lack of implied meaning is to either add detail (which narrows the gap on guard continue) or rename the keyword to something. In terms of the clarity Iā€™m actually disappointed that Swift doesnā€™t use the do keyword for loops, as I find the following very clear:

  for eachValue in theValues where eachValue.isOdd do { ā€¦ }

Reading the last part in isolation ā€œwhere eachValue.isOdd doā€ is clearer that the block is skipped, but that the loop isnā€™t. This is essentially how I read loop blocks already, but since we have a ā€œdoā€ keyword I wish we could use it like this, as I would on all my loops. In fact, with the do present you could easily shorten ā€œwhereā€ to ā€œifā€, which may even be slightly clearer still:

  for eachValue in theValues if eachValue.isOdd do { ā€¦ }

This is part of why Iā€™m uncertain about relocating where, as I kind of feel that itā€™s actually in the right place already, since the where clause determines whether the block is executed, not whether the loop stops, i.e- the program will still visit every element of the sequence if it can, youā€™re just choosing which ones to actually do work for. Even clearer still if you consider it with a comma in the middle like so:

  for eachValue in theValues, if eachValue.isOdd do { ā€¦ }

Not really proposing this is a syntax, though if it were possible to write this way today itā€™s what Iā€™d do, but the last form above is how I ready a where clause on a for loop. Iā€™ve said that itā€™s equivalent to a guard because a guard is a nice way to replace it when the condition becomes more complex (or you need to break instead), but actually Iā€™d say itā€™s more equivalent to:

  for eachValue in theValues { if eachValue.isOdd {
    ā€¦
  }}

Except Iā€™d never want to write my code that way if I can avoid it (I frequently write code like this for switch statements inside enums, which is Iā€™m eager to see a replacement to switch self, but thatā€™s another issue entirely).

Also, one thing to add is that I really hate writing extra lines if I donā€™t have to; obviously Iā€™ll do it when a single line gets too complex and cluttered, but one reason I like where is that I donā€™t have to waste a line inside the loop on a guard statement, which either keeps the focus on the code, or lets me instead use the line for a comment that clarifies my intent exactly; Iā€™m all for self-documenting code, but a comment stating what my aim is better since any mistake in my code could leave my intent in question otherwise.

Ā·Ā·Ā·

On 10 Jun 2016, at 19:10, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:
So "inessential" alone is not a good sole criterion--I agree. But it is one of several prongs here: `where` is not only inessential, I argue that it lacks expressiveness (in that what is enabled by it can be expressed equally or even more cogently with `guard`, a more general and more expressive syntax overall), and it detracts from rather than helps with writing correct code, because we hear attestations that its use has gone awry (and the going awry happens at runtime!). So in essence, I would be content with inessential but expressive solutions, but here I argue that `where` is neither essential nor expressive.