[swift-evolution] Add a while clause to for loops
Xiaodi Wu
xiaodi.wu at gmail.com
Wed Jun 8 19:26:24 CDT 2016
Well put; an excellent articulation of concerns arising from the daily
experience of using the feature.
On Wed, Jun 8, 2016 at 19:14 Shawn Erickson <shawnce at gmail.com> wrote:
> 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.
>
> If you separate the loop statement (what you are looping over) from the
> filter (continue) conditions and/or termination conditions (break, guard) I
> also feel it can be clearer to eyeball quickly. Additionally it lends
> itself to being debugged in a line based debugger.
>
>
> -Shawn
> On Wed, Jun 8, 2016 at 9:11 AM Xiaodi Wu via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> On Wed, Jun 8, 2016 at 3:38 AM, Haravikk <swift-evolution at haravikk.me>
>> wrote:
>>
>>>
>>> On 8 Jun 2016, at 01:54, Xiaodi Wu via swift-evolution <
>>> swift-evolution at swift.org> wrote:
>>>
>>> 1) It is spelled out exactly what happens when a condition is met. I no
>>> longer have to remember whether the word that describes breaking from a
>>> loop uses a place analogy ("where") or a time analogy ("while" or "when”).
>>>
>>>
>>> (You cannot convince me that these words are intuitive when the meaning
>>> of "where" changes by context in today's Swift. Now, if you want to propose
>>> that these be named "breakif" and "continueif" instead, then I'd agree with
>>> you that they're intuitive names, but then they'd also be really ugly.)
>>>
>>>
>>> I’m not sure I agree that this is confusing,
>>>
>>
>> Why would breaking from a loop intuitively use a place analogy and
>> continuing to the next iteration use a time analogy? This is totally made
>> up; hence, it is not intuitive. I make no argument about whether or not it
>> would be conceptually confusing. If you renamed 'break' to 'foo' and
>> 'continue' to 'bar', it would not be intuitive, but you could likewise
>> argue that it's not confusing, in that 'foo' is clearly not 'bar'.
>>
>>
>>> a little extra to learn for new programmers perhaps but I think it’s
>>> fairly intuitive:
>>>
>>> while let value = foo.next() where someCondition(value) { … }
>>>
>>> This reads to me as “repeat the following block until this fails to be
>>> true”, the conditional binding in this case fails to be true if
>>> someCondition(value) isn’t true, so the loop ends. I think the key thing
>>> here is that the where clause is for the conditional binding and not the
>>> loop itself, so in this respect it behaves exactly like an if or guard
>>> statement. Meanwhile:
>>>
>>> for eachValue in theValues where someCondition(eachValue) { … }
>>>
>>> Reads as “for everything in theValues do the following if
>>> someCondition(eachValue) is also true”, in other words this loop always
>>> tries to visit every element of the sequence (a while loop has no implicit
>>> awareness of the sequence, it’s really just an if statement that runs over
>>> and over). In this case the where clause is part of the loop itself. There
>>> may be an argument that where should be renamed on for loops to better
>>> distinguish this, but once you consider that there’s no pattern or
>>> conditional binding here I think it makes a reasonable amount of sense.
>>>
>>> Yes this could be handled by an if/guard statement with continue, and
>>> while as proposed here could be done with the same plus a break, but these
>>> things come up so often that it just makes a lot of sense to get it all
>>> neatly onto one line.
>>>
>>
>> As I pointed out above with Tim's example, putting it all on one line is
>> absolutely not 'neat'--it reads like spaghetti. That is one major beef I
>> have with this proposal: that it *encourages* writing on one line too many
>> things that, whether you use `where` or not, are much more clearly written
>> on multiple lines. If writing everything on one line is for you the major
>> advantage of this proposal, we could agree on everything else and I would
>> be very much opposed to this proposal on that basis alone.
>>
>>
>>> Chaining methods can do this, but it’s actually less readable IMO, or
>>> requires multiple lines to keep it clear which defeats the point.
>>>
>>
>> For me, encouraging the use of multiple lines is the point. Tim's example
>> demonstrated to me very clearly that clarity is not served by additional
>> sugar to reduce the amount of punctuation on one line; it is served only by
>> putting things on multiple lines. As I said above, I would cringe to read a
>> loop that begins `for foo in bar where something while somethingElse where
>> yetAnotherSomething while againAnotherSomething { ... }`.
>>
>>
>>> As with where on if/guard statements it’s about keeping the simpler,
>>> more common cases as clean and readable as possible. If the re-use of the
>>> keyword where on the for loop is confusing then that’s an argument for
>>> renaming that, rather than rejecting while or ditching the whole thing IMO.
>>> Personally I think it’s okay, you just have to think what the where clause
>>> is actually acting upon.
>>>
>>> 3) I have the flexibility to do something between the first if statement
>>> and the second if statement, if I want. By placing the break statement at
>>> the end of my loop, I could effectively choose to have one more iteration
>>> than if I placed it at the beginning of my loop. There is nothing you can
>>> do to mimic that choice with your proposed while clause, unless you want to
>>> also propose a `for...in...repeat { } while` syntax.
>>>
>>>
>>> So? Like where clauses this is for the simpler cases, if you want to do
>>> something more complex you remain free to use more complex conditionals.
>>>
>>
>> And I was/am a proponent of SE-0099 to remove `where` from if and while
>> loops; and if that succeeds I will definitely solicit comments to remove it
>> from for loops!
>>
>>
>>> A lot of the time you don’t need this however, so it makes sense to
>>> simplify the common case while leaving the complex one just as useful as it
>>> is today. Nothing about this proposal would stop you from using if/guard
>>> conditions inside the loop.
>>>
>>> 4) This is the perhaps the important point. A beginning programmer--not
>>> any of us, presumably, but we were all beginners once--can accomplish
>>> everything that he or she desires without learning this new proposed
>>> syntax. Almost all texts, I believe, teach if statements before loops, and
>>> teach break and continue in the same breath as the loops themselves.
>>>
>>>
>>> In terms of teaching there shouldn’t be a problem with just teaching the
>>> basic building blocks first, then showing off simplifications later. As
>>> with any coding the most important thing is to get the intended behaviour
>>> correct, simplifying or optimising the code can always come later.
>>>
>>> You could argue the same thing about the shorthands around closures; I’m
>>> not sure why but I had trouble with those initially until after I’d worked
>>> with them in the more verbose form (with fully named parameters and a
>>> return statement) till I started to get the logic behind it, now I can just
>>> right a quick closure with the dollar sign shorthand.
>>>
>>
>> Closures are--I'm sure you'd agree--a far more advanced concept than
>> loops. Concepts like closing over a variable are very, very hard. Many
>> useful things can be written without using closures. Not so many things
>> could do without loops. It very much matters that a learner might feel that
>> he or she cannot understand everything about a loop with the handwavy
>> explanation that it'll "come later". One critique of using Java as a
>> starting language is that you are forced to teach your students on day one
>> that the real meaning of the words "public static void main(String[] args)"
>> will "come later".
>>
>>
>>>
>>> A good linter could be written to detect the presence of a simple
>>> if/guard right inside the loop and could then suggest the use of
>>> where/while as appropriate.
>>>
>> _______________________________________________
>
>
>> 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/20160609/dc5da445/attachment.html>
More information about the swift-evolution
mailing list