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

Xiaodi Wu xiaodi.wu at gmail.com
Mon Jun 13 12:10:05 CDT 2016


On Mon, Jun 13, 2016 at 12:01 PM, let var go <letvargo at gmail.com> wrote:

> Well, the "harmful" nature of it is something that still hasn't been
> established as far as I'm concerned. I came to this discussion a little
> late, but after reading through as many old email comments as I could find,
> the only harm is an undocumented report that somewhere there were some
> relatively new users to Swift who had to ask a question about how
> for-in-where worked. If you have more information about how widespread this
> problem is and how much trouble it is really causing in the world, then
> please provide it.
>

Shawn Erickson gave a pretty compelling account on June 8. I can't tell you
how widespread it is in the world, since existence of the feature itself
does not seem to be widely known. I can tell you that the working of the
`where` clause was thought to be confusing enough that it's explicitly
called out in _Advanced Swift_, hardly a text addressed to new users. Thus,
this proposal. If the core team, with their perspective on internal and
external users, agrees that this is a problem, then it'll go. If not, then
it'll stay.


>
> On Mon, Jun 13, 2016 at 9:50 AM let var go <letvargo at gmail.com> wrote:
>
>> No, the key difference between for...in and forEach is that for...in
>> allows for early exit. They both allow you to 'continue', though in forEach
>> it is called 'return':
>>
>> // This prints odd numbers, skipping ("continuing") past the even numbers:
>> (0..<100).forEach { if $0 % 2 == 0 { return } else { print($0) } }
>>
>> Early-exit ('break') is a different beast and requires a for...in loop.
>>
>> You missed my main point. In some situations even 'continue' may prove to
>> be useful. It is not my preferred method.
>>
>> Why do you say, "Swift is not a live-and-let-live language?" Where do you
>> get that from? Are you really saying that there is not room in the Swift
>> community for people with different coding styles and preferences? I truly
>> believe that that attitude will be very harmful to the long term future of
>> the language.
>>
>> On Mon, Jun 13, 2016 at 9:29 AM Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>
>>> See, the key difference between for...in and .forEach() is that one
>>> allows for continue and break and the other doesn't. Swift is not a
>>> live-and-let-live language: if you truly believe that using continue leads
>>> to bad code, then propose its removal or the removal of for...in altogether.
>>>
>>> On Mon, Jun 13, 2016 at 11:21 let var go <letvargo at gmail.com> wrote:
>>>
>>>> No, I wouldn't eliminate 'continue'. Even though I consider it a
>>>> sub-optimal solution, I would keep it in the language. Why? A couple of
>>>> reasons:
>>>>
>>>> 1) I don't like it, but even 'continue' may be the best available
>>>> solution in the context of a particular problem. I will look for other
>>>> options first, but I don't rule out the possibility that there might come a
>>>> time when it is the right tool for the job.
>>>>
>>>> 2) Some people like it. Not everyone feels the same way about it as me.
>>>> Some of the people who like it are better programmers than me. I have a lot
>>>> to learn, and someday I might discover that I love 'continue' after all.
>>>> Until then, live-and-let-live is what I say. Everyone should control their
>>>> own flow :) Keep your hands off my 'where' and I'll keep my hands off your
>>>> 'continue' :)
>>>>
>>>> On Mon, Jun 13, 2016 at 8:56 AM Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>>>
>>>>> On Mon, Jun 13, 2016 at 10:44 AM, let var go <letvargo at gmail.com>
>>>>> wrote:
>>>>>
>>>>>> I think we must be reading different discussions.
>>>>>>
>>>>>> What I have seen in this discussion is the following:
>>>>>>
>>>>>> a) The need to filter a for-in loop doesn't arise that often; but,
>>>>>> b) When it does arise, everyone who has chimed in on this thread
>>>>>> (except the two people who are proposing the change) thinks that the
>>>>>> "where" clause is the clearest, most expressive way to do it.
>>>>>>
>>>>>> Something that would help me get on board with this change is more
>>>>>> evidence about what kind of problems it is actually creating.
>>>>>>
>>>>>> As best I can tell, this proposal got started because "somewhere"
>>>>>> some new programmers (no one knows how many) expressed some confusion (no
>>>>>> one knows how seriously they were confused, or how long it took them to
>>>>>> figure it out) about how the where clause worked in a for-in loop. For all
>>>>>> we know, once they learned the way it works, they may have said, "Hey
>>>>>> that's cool! I'm gonna use that from now on!"
>>>>>>
>>>>>> In other words, you seem to be talking about removing a feature that
>>>>>> is liked by *a lot* people, based on some unsubstantiated reports of user
>>>>>> error that may or may not have been totally unsubstantial.
>>>>>>
>>>>>> I don't want new programmers to be confused, either, but the "where"
>>>>>> clause is such a basic programming construct - the keyword is new, but the
>>>>>> idea itself is as old as programming - that I don't mind expecting new
>>>>>> programmers to learn how to use it. The learning curve should be incredibly
>>>>>> short - it is nothing more than a filter operation.
>>>>>>
>>>>>> There's something else here that is really important to me, though I
>>>>>> don't know how others feel about it.
>>>>>>
>>>>>> Using the guard...continue approach that you are promoting is a code
>>>>>> smell. It puts control-flow logic inside the for-in loop. That is something
>>>>>> I have always tried to avoid. I know that the language allows for it, but I
>>>>>> believe it is bad programming practice. In fact, if you get rid of the
>>>>>> `where` keyword, I'm still not going to use guard...continue. I'll just
>>>>>> filter the collection first and then loop it.
>>>>>>
>>>>>
>>>>> This is quite the statement. It sounds like you'd be for the
>>>>> elimination of `continue`?
>>>>>
>>>>>
>>>>>>
>>>>>> It is a code smell for the same reason that messing with the index
>>>>>> inside a for;; loop was a code smell. I was always taught never to do this:
>>>>>>
>>>>>> for var i = 0; i < array.count, i++ {
>>>>>>   if iWantThisToLoopAnExtraTime {
>>>>>>     i--
>>>>>>   }
>>>>>> }
>>>>>>
>>>>>> Why? Because code like that is confusing. It becomes difficult to
>>>>>> know how many times the loop will execute, what the looping logic is, etc.
>>>>>> Sure, I might get away with it most of the time, but it is bad practice and
>>>>>> there is always a better way to do what you want to do. The only thing that
>>>>>> keeps you from the better way is laziness.
>>>>>>
>>>>>> The same is true (albeit to a lesser degree) for the
>>>>>> guard...continue. It may not be as extreme, but it is still a code smell.
>>>>>> It divides the control-flow logic into two parts - one outside the loop,
>>>>>> and one inside the loop, and it suddenly becomes twice as easy to miss
>>>>>> something.
>>>>>>
>>>>>> Using for-in-where, all of the control-flow logic is on one single
>>>>>> line, and once it is known that "where" operates as a filter operation, it
>>>>>> all works together in a single, harmonious statement that declares exactly
>>>>>> what is going to happen in a way that is totally unambiguous.
>>>>>>
>>>>>> So by getting rid of the "where" clause, I believe that you are
>>>>>> actually encouraging bad programming practice. Instead of encouraging the
>>>>>> new user to learn this very simple construct that will ultimately make
>>>>>> their code safer and more expressive without dividing their control-flow
>>>>>> logic unnecessarily into two separate parts, you are encouraging them to
>>>>>> just "do what they know". I think that is terrible, and you are doing them
>>>>>> a disservice.
>>>>>>
>>>>>> And from a personal standpoint, you are telling me that I have to
>>>>>> write smelly code, even though there is this perfectly good non-smelly
>>>>>> option sitting right there, because you don't want someone else to have to
>>>>>> learn something.
>>>>>>
>>>>>> On Mon, Jun 13, 2016 at 5:29 AM Xiaodi Wu <xiaodi.wu at gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> I think this discussion has made it pretty plain that what is
>>>>>>> claimed to be 'so useful' is barely ever used. Moreover, it provides no
>>>>>>> independent uses. The point of these pitches is to sound out arguments,
>>>>>>> not, as far as I was aware, to take a vote.
>>>>>>>
>>>>>>> On Mon, Jun 13, 2016 at 1:54 AM Jose Cheyo Jimenez <
>>>>>>> cheyo at masters3d.com> wrote:
>>>>>>>
>>>>>>>> --1
>>>>>>>>
>>>>>>>> I think it would be a waste of the community's time to do a formal
>>>>>>>> review when only two people are in favor of this removal.
>>>>>>>>
>>>>>>>> 'for in where' is so useful especially since we don't have for;;;
>>>>>>>> loops anymore. I'd say leave this alone; the majority doesn't want this
>>>>>>>> changed.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Jun 10, 2016, at 10:17 AM, Xiaodi Wu via swift-evolution <
>>>>>>>> swift-evolution at 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.
>>>>>>>>
>>>>>>>> On Fri, Jun 10, 2016 at 12:10 let var go <letvargo at 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 at swift.org> wrote:
>>>>>>>>>
>>>>>>>> On Fri, Jun 10, 2016 at 11:23 AM, Sean Heber via swift-evolution <
>>>>>>>>>> swift-evolution at 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 at swift.org
>>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>>>>>>
>>>>>>>>>> _______________________________________________
>>>>>>>>>> swift-evolution mailing list
>>>>>>>>>> swift-evolution at swift.org
>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>>>>>
>>>>>>>>> _______________________________________________
>>>>>>>> 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/20160613/32525244/attachment.html>


More information about the swift-evolution mailing list