C-style For Loops


(Clemens Wagner) #1

We’ve developed a number of Swift apps for various clients over the past year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like C-loops and increment or decrement operators of a programming language. How about the developers and the productive code which used C-style loops already?

I understand the reasons why you, Erica and the others don’t like C-style loops. But changing the philosophy of a productive programming language is a very bad idea.

Cheers
Clemens


Joining Old Orphaned Posts to the Main Threads
(Chéyo Jiménez) #2

https://github.com/apple/swift/commit/0d001480a94f975355cd458973d5c51cef55bff1

···

On Sunday, December 6, 2015, Clemens Wagner via swift-evolution < swift-evolution@swift.org> wrote:

> We’ve developed a number of Swift apps for various clients over the past
year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like
C-loops and increment or decrement operators of a programming language. How
about the developers and the productive code which used C-style loops
already?

I understand the reasons why you, Erica and the others don’t like C-style
loops. But changing the philosophy of a productive programming language is
a very bad idea.

Cheers
Clemens
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <javascript:;>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Erica Sadun) #3

Last week, I made the following proposal for Swift:

The C-style for-loop appears to be a mechanical carry-over from C rather than a genuinely Swift-specific construct. It is rarely used and not very Swift-like.

More Swift-typical construction is already available with for-in statements and stride. Removing for loops would simplify the language and starve the most common use-points for -- and ++, which are already due to be eliminated from the language.

The value of this construct is limited and I believe its removal should be seriously considered.

Yesterday, I was on family time. Today, I am grabbing a little Swift-break to respond to the discussion I otherwise missed on-list. Please forgive the lateness of this response.

Lack of Language Necessity

Clemens writes:

We’ve developed a number of Swift apps for various clients over the past year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like C-loops and increment or decrement operators of a programming language. How about the developers and the productive code which used C-style loops already?

I understand the reasons why you, Erica and the others don’t like C-style loops. But changing the philosophy of a productive programming language is a very bad idea.

I don't think the C-style loop was ever really part of the language philosophy. It feels like a vestigial feature that no one ever got around to cleaning up. Its entire functionality is easily replaced by other, existing Swift constructs. While Swift design deliberately held onto C-like features for familiarity, I see no special benefit to retaining the for-loop.

In contrast, consider fallthrough. There was a discussion on Friday about fallthrough, and it quickly became apparent that losing this language feature would have a significant impact on a few key algorithms. Several list participant were able to pop forward and say "without this feature, I would not be able to do X, Y or Z". I see no parallel case to be made for for-loops.

Lowered Readability and Maintainability

I have aesthetic reasons for disliking the for-loop. The C-style loop is harder to read especially for those not coming from C-style languages, easier to mess up at edge conditions, and is commonly used for side-effects which, in a language focused on safety, is not a feature to be encouraged.

For example, one side effect that was mentioned on-list yesterday was the incrementor, which is guaranteed in C-style to execute late:
Roland King writes:

for var floatingThing = start ; floatingThing <= end ; floatingThing += delta
{
  // more than a few lines of code with early escape continues
}

shows intent of the loop very clearly, start, condition and increment all together at the top, and however you loop you always execute the increment part of the statement. Convert that to a while(), if you have a continue in the body, you have a good chance of not incrementing at all, or duplicating the increment code before every continue. So you can’t always nicely turn for into while. I second the point below about the loop variable being local to the for as well, I also like that.

Late incrementor management is a feature that can be mimicked with defer, as pointed out by several other list members.

Another complaint regarded a loss of succinctness. Per Melin wrote:

Another example from the same LinkedList class. It finds the right place to insert a new node:

  for next = head; next != nil && index > 0; prev = next, next = next!.next, --index { }

Extreme? Probably, but I like it better than the same thing done in five lines of while loop.

I'd argue that readability and maintainability are core API goals. Clarity is always to be preferred to brevity. Let me point you to Justin Etheredge's essay "Don't be clever" (http://www.codethinked.com/dont-be-clever).

So next time you go to write a super clever line of code, think to yourself "Will the benefits of this super cleverness be outweighed by the future issues in maintaining and understanding the code?" And if there is anyhesitation at all, then you better not be clever, because 3 months from now you will come across that code and say "What the hell was I thinking?" Then you’ll end up rewriting it anyway.

Incrementor Challenges

Another complaint involved forgetting or misplacing the incrementor when transforming items to while loops. There are two cases being glommed together here, and I'd like to separate them.

First, there's a collection case, in which the collection provides its own indices. In such implementations, there's simply no need to manually declare and manage an index. You can use for-in.

Second, there's what I'm going to call the bitmap case, where an index may refer to geometrically-related indices, which happens often in image processing. (I'm going to repress any "Just use Accelerate" rant. This is a significant area of programming). Here's some pseudocode that demonstrates how this might look in a for-loop-less Swift implementation:

    for row in 0..<height {
        for column in 0..<width {
            var sum: UInt = 0
            for rowOffset in -1...1 {
                for columnOffset in -1...1 {
                    let index = pixelOffsetAt(row + rowOffset, column + columnOffset) + redChannelOffset
                    sum += pixels[index]
                }
            }
            let currentRedPixelBlurredAverage = sum / 9
            // blah blah other stuff
        }
    }

Again, I don't see anything that would limit relative indexing with this proposal.

The Skip Case

Matthijs Hollemans writes,

Another benefit of a C-style for loop is that it simply ignores the loop when n <= i, as in the following example,

  for var i = 100; i < n; ++i { ...

while the Swifty version gives an error because it cannot create a range where the end is smaller than the start:

  for i in 100..<n { ...

Of course, you can add an if-statement to catch this but in the C-style loop this is implicit. Hence, it is more expressive.

I may be in the minority but I rather like that this becomes an error. The "skip" behavior reads to me as an unintended side-effect rather than a purposeful design goal. I prefer a philosophy that minimizes such possibilities in a safe modern language.

Issues of Type

Roland King writes,

I must be the only person who still likes C-style for loops on occasion. eg a loop with something floating point

I counter that stride addresses this for all conforming strideable types, not just floating point values.

Training Costs and Migration Benefits

The main argument against losing the feature seems to be the higher training costs for C-style coders and the higher porting costs for existing C-code. I'd argue that the training costs to a new language are significant and whether there's a C-style for loop will not materially change those overall costs, especially for those moving from Objective-C where the for-in loop is common. Second, porting to Swift should be motivated by an enhancement of safety and maintainability. Swift already supports external calls to C routines. If you want to keep your code in C, there's nothing stopping you from doing so. (Or to put it in American Politician-speak, "If you like your C-code, you can keep your C-code")

More Direct Swift Replacements

After all this discussion, let me end with a suggestion proposed by Joe Groff for anyone who would still miss the for-loop by approximating the same control flow in native Swift:

func cStyleFor(@autoclosure init initializer: () -> (), @autoclosure test: () -> Bool, @autoclosure inc: () -> (), body: () throws -> ()) rethrows {
  // left as an exercise
}

var i = 0
cStyleFor(init: i = 0, test: i < 10, inc: ++i) {
  print(i)
}

-Joe

The only feature this does not include, as pointed out by list members, is a co-declared variable binding. In a C-style for-loop, the "i" is bound as part of the declaration. In this implementation, it requires a separate declaration line and remains in the scope for its lifetime.

Wrap-up

I hope I have addressed the concerns brought up on-list. If I missed one of yours please feel free to reply. The voting and review period will be between 7 Dec and 10 Dec. Here is the master schedule: https://github.com/apple/swift-evolution/blob/master/schedule.md

Best regards,

-- Erica

···

On Dec 6, 2015, at 7:47 AM, J. Cheyo Jimenez via swift-evolution <swift-evolution@swift.org> wrote:

https://github.com/apple/swift/commit/0d001480a94f975355cd458973d5c51cef55bff1

On Sunday, December 6, 2015, Clemens Wagner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> We’ve developed a number of Swift apps for various clients over the past year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like C-loops and increment or decrement operators of a programming language. How about the developers and the productive code which used C-style loops already?

I understand the reasons why you, Erica and the others don’t like C-style loops. But changing the philosophy of a productive programming language is a very bad idea.

Cheers
Clemens
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <javascript:;>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Paul Cantrell) #4

I’d like to express my pure joy at a proposal to _remove_ a feature from a popular language.

My favorite Swift feature? Its brilliant insights that optionality should be a characteristic of _types_ but mutability should be a characteristic of _variables_ are right up there. But no, my favorite feature of Swift so far is its willingness to make breaking language changes. Hallelujiah!

Fear of removing features and making breaking changes is what doomed Java to its current status of “most used, most sneered at.” It’s what’s turned C++ into the world’s largest ball of twine. Swift is wise to set the early precedent of carefully considered breaking language changes.

We’ve developed a number of Swift apps for various clients over the past year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like C-loops and increment or decrement operators of a programming language.

I cannot imagine a better case for removing a language feature.

We have a feature that is:

1. not widely used,
2. easily replaced with other languages features where it is used, and
3. inconsistent with the language’s general aesthetic.

Theory, observation, and taste agree. If this isn’t a feature to remove for the health of the language, then what is?

Cheers,

Paul

–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
https://innig.net@inthehandshttp://siestaframework.com/


(Tyler Cloutier) #5

Lowered Readability and Maintainability

I have aesthetic reasons for disliking the for-loop. The C-style loop is harder to read especially for those not coming from C-style languages, easier to mess up at edge conditions, and is commonly used for side-effects which, in a language focused on safety, is not a feature to be encouraged.

For example, one side effect that was mentioned on-list yesterday was the incrementor, which is guaranteed in C-style to execute late:
Roland King writes:

for var floatingThing = start ; floatingThing <= end ; floatingThing += delta
{
  // more than a few lines of code with early escape continues
}

shows intent of the loop very clearly, start, condition and increment all together at the top, and however you loop you always execute the increment part of the statement. Convert that to a while(), if you have a continue in the body, you have a good chance of not incrementing at all, or duplicating the increment code before every continue. So you can’t always nicely turn for into while. I second the point below about the loop variable being local to the for as well, I also like that.

Late incrementor management is a feature that can be mimicked with defer, as pointed out by several other list members.

Defer wouldn’t accomplish the exact same behavior because it would run if an exception was thrown, which is not the same as the last clause of a for loop, but perhaps is close enough.

The only other concern I would have is not being able to scope my variables to the loop. I didn’t see it addressed, but perhaps its not very important in the end anyway.

Something like the following might be nice to scope the variable exclusively to the loop.

for var x = 0 while (someCondition()) {
  // code
}


(Michel Fortin) #6

There is actually one good reason I see in favor of keeping the C-style for loop, and only one: ease of porting existing code to Swift.

If you are porting code from another language that uses C-style for loops, currently you can keep the loop as is while you translate all the syntactic differences everywhere. If Swift didn't had a C-style for loop, then you'd need to rethink the control flow at the same time you are converting everything else, increasing the risk of errors during what is already a delicate operation.

C-style for loops are very common in code you can find everywhere because many languages have it, and therefore there is a lot of algorithms, sometime tricky algorithms you don't want to mess up, that rely on such loops. Even if you had the desire to convert all of them to for-in loops in your port, rewriting the control flow *at the same time* you are addressing all the other porting issues is much worse than doing it in a separate step *after* the crude port has been tested to work.

In other words: you should avoid refactoring everything in one step. The C-style for loop enables that.

···

--
Michel Fortin
michel.fortin@michelf.ca
https://michelf.ca


(Clemens Wagner) #7

Hi,

a little bit more explanation would be very helpful and welcome.

Cheers
Clemens

···

Am 06.12.2015 um 15:47 schrieb J. Cheyo Jimenez <cheyo@masters3d.com>:

https://github.com/apple/swift/commit/0d001480a94f975355cd458973d5c51cef55bff1

On Sunday, December 6, 2015, Clemens Wagner via swift-evolution <swift-evolution@swift.org> wrote:
> We’ve developed a number of Swift apps for various clients over the past year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like C-loops and increment or decrement operators of a programming language. How about the developers and the productive code which used C-style loops already?

I understand the reasons why you, Erica and the others don’t like C-style loops. But changing the philosophy of a productive programming language is a very bad idea.

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


(inbox only) #8

True,even that a feature isn't used doesn't mean that you need to remove
that feature.
I hope that the proposal will be rejected.

···

2015-12-06 12:03 GMT+02:00 Clemens Wagner via swift-evolution < swift-evolution@swift.org>:

> We’ve developed a number of Swift apps for various clients over the past
year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like
C-loops and increment or decrement operators of a programming language. How
about the developers and the productive code which used C-style loops
already?

I understand the reasons why you, Erica and the others don’t like C-style
loops. But changing the philosophy of a productive programming language is
a very bad idea.

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


(Per Melin) #9

No worries, but for the record, I did absolutely not write that. I *quoted*
that. I think that C-style 'for' is a horrible mess that should be killed
with fire.

···

On Sun, Dec 6, 2015 at 5:59 PM, Erica Sadun via swift-evolution < swift-evolution@swift.org> wrote:

Another complaint regarded a loss of succinctness. Per Melin wrote:

Another example from the same LinkedList class. It finds the right place
to insert a new node:

  for next = head; next != nil && index > 0; prev = next, next = next!.
next, --index { }

Extreme? Probably, but I like it better than the same thing done in five
lines of while loop.


(Don Wills) #10

I too hope that the proposal to remove C-style loops is rejected. Yes, they aren't that necessary any more, but if we want Swift to compete with Java, C#, C++ and C, there is no reason to remove basic features like C-style loops just because they are politically incorrect. If there was a functional reason, I might get on board with removing it, but there isn't.

I also hope that the decision to remove increment and decrement operators is reversed using the same logic. Just because *you* don't like something that has been a feature of dozens of programming languages for 40 years doesn't mean removing that feature is a good idea. One man's goto statement is another man's Leatherman multi-tool. And FWIW, if C-style loops stay in the language, they become much more ugly without increment and decrement.

Don Wills

···

On Dec 6, 2015, at 8:33 AM, inbox only via swift-evolution <swift-evolution@swift.org> wrote:

True,even that a feature isn't used doesn't mean that you need to remove that feature.
I hope that the proposal will be rejected.

2015-12-06 12:03 GMT+02:00 Clemens Wagner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:
> We’ve developed a number of Swift apps for various clients over the past year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like C-loops and increment or decrement operators of a programming language. How about the developers and the productive code which used C-style loops already?

I understand the reasons why you, Erica and the others don’t like C-style loops. But changing the philosophy of a productive programming language is a very bad idea.

Cheers
Clemens
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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


(David Waite) #11

Nearly every for loop I’ve written in other languages has used pre or post increment (depending on the language), which is being removed in Swift 3.0. It makes sense for 'for loops' to go if pre/post increment goes away.

-DW

···

On Dec 6, 2015, at 9:03 AM, Don Wills via swift-evolution <swift-evolution@swift.org> wrote:

I too hope that the proposal to remove C-style loops is rejected. Yes, they aren't that necessary any more, but if we want Swift to compete with Java, C#, C++ and C, there is no reason to remove basic features like C-style loops just because they are politically incorrect. If there was a functional reason, I might get on board with removing it, but there isn't.

I also hope that the decision to remove increment and decrement operators is reversed using the same logic. Just because *you* don't like something that has been a feature of dozens of programming languages for 40 years doesn't mean removing that feature is a good idea. One man's goto statement is another man's Leatherman multi-tool. And FWIW, if C-style loops stay in the language, they become much more ugly without increment and decrement.

Don Wills

On Dec 6, 2015, at 8:33 AM, inbox only via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

True,even that a feature isn't used doesn't mean that you need to remove that feature.
I hope that the proposal will be rejected.

2015-12-06 12:03 GMT+02:00 Clemens Wagner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:
> We’ve developed a number of Swift apps for various clients over the past year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like C-loops and increment or decrement operators of a programming language. How about the developers and the productive code which used C-style loops already?

I understand the reasons why you, Erica and the others don’t like C-style loops. But changing the philosophy of a productive programming language is a very bad idea.

Cheers
Clemens
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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

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


(Erica Sadun) #12

My apologies! -- E

···

On Dec 6, 2015, at 11:08 AM, Per Melin <p@greendale.se> wrote:

On Sun, Dec 6, 2015 at 5:59 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Another complaint regarded a loss of succinctness. Per Melin wrote:

Another example from the same LinkedList class. It finds the right place to insert a new node:

  for next = head; next != nil && index > 0; prev = next, next = next!.next, --index { }

Extreme? Probably, but I like it better than the same thing done in five lines of while loop.

No worries, but for the record, I did absolutely not write that. I *quoted* that. I think that C-style 'for' is a horrible mess that should be killed with fire.


(Erica Sadun) #13

That is very odd indeed.

If you add explicit capture, the issue goes away:

var handlers: [() -> Void] = []

for i in 0..<5 {
    handlers.append {[i] in print(i, terminator:",") }
}

for handler in handlers {
    handler() // "0 1 2 3 4"
}

handlers = []

for var i = 0; i < 5; i += 1 {
    handlers.append {[i] in print(i, terminator:",") }
}

print("")
for handler in handlers {
    handler() // was "5 5 5 5 5", now 1, 2, 3, 4, 5
}

It really seems like a bug to me rather than a feature of the for-loop

-- Erica

···

On Dec 6, 2015, at 12:03 PM, Kelly Gerber via swift-evolution <swift-evolution@swift.org> wrote:

I think that the C-style for loop should be removed from Swift. The scope rules for this for loop are wrong. Every loop sees the same scope. This is a source of bugs if you export the loop variable name outside the scope of the for statement, for example in a closure. The following code illustrates the problem:

var handlers: [() -> ()] = []

for i in 0..<5 {
    handlers.append { print(i) }
}

for handler in handlers {
    handler() // "0 1 2 3 4"
}

handlers = []

for var i = 0; i < 5; i += 1 {
    handlers.append { print(i) }
}

for handler in handlers {
    handler() // "5 5 5 5 5"
}

The Swift for-in loop does the right thing naturally. The C-style for loop does the wrong thing naturally. Removing the C-style for loop from Swift will eliminate one more class of possible errors from the language.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Matthew Johnson) #14

+1 on embracing breaking change as necessary for moving the language forward!

···

On Dec 6, 2015, at 1:08 PM, Paul Cantrell via swift-evolution <swift-evolution@swift.org> wrote:

I’d like to express my pure joy at a proposal to _remove_ a feature from a popular language.

My favorite Swift feature? Its brilliant insights that optionality should be a characteristic of _types_ but mutability should be a characteristic of _variables_ are right up there. But no, my favorite feature of Swift so far is its willingness to make breaking language changes. Hallelujiah!

Fear of removing features and making breaking changes is what doomed Java to its current status of “most used, most sneered at.” It’s what’s turned C++ into the world’s largest ball of twine. Swift is wise to set the early precedent of carefully considered breaking language changes.

We’ve developed a number of Swift apps for various clients over the past year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like C-loops and increment or decrement operators of a programming language.

I cannot imagine a better case for removing a language feature.

We have a feature that is:

1. not widely used,
2. easily replaced with other languages features where it is used, and
3. inconsistent with the language’s general aesthetic.

Theory, observation, and taste agree. If this isn’t a feature to remove for the health of the language, then what is?

Cheers,

Paul

–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
https://innig.net@inthehandshttp://siestaframework.com/

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


(Colin Barrett) #15

Nearly every for loop I’ve written in other languages has used pre or post increment (depending on the language), which is being removed in Swift 3.0. It makes sense for 'for loops' to go if pre/post increment goes away.

I’m not 100% convinced by this line of reasoning (using the += form or successor() isn’t THAT clunky) but it is awfully poetic.

Fun fact, you write (albiet with different syntax) C-style for-loops as library code:

for i in CStyle(0, {$0 < 20}, {$0 += 1}) {
// do something 20 times
}

Where CStyle is just a straightforward implementation of SequenceType. (Tuples allow for simultaneous iteration, which is usually when I end up with C-style for-loops)

(Apologies if this was mentioned up thread, I’ve only just recently joined the list)

-Colin

···

On Dec 6, 2015, at 11:31 AM, David Waite via swift-evolution <swift-evolution@swift.org> wrote:

-DW

On Dec 6, 2015, at 9:03 AM, Don Wills via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I too hope that the proposal to remove C-style loops is rejected. Yes, they aren't that necessary any more, but if we want Swift to compete with Java, C#, C++ and C, there is no reason to remove basic features like C-style loops just because they are politically incorrect. If there was a functional reason, I might get on board with removing it, but there isn't.

I also hope that the decision to remove increment and decrement operators is reversed using the same logic. Just because *you* don't like something that has been a feature of dozens of programming languages for 40 years doesn't mean removing that feature is a good idea. One man's goto statement is another man's Leatherman multi-tool. And FWIW, if C-style loops stay in the language, they become much more ugly without increment and decrement.

Don Wills

On Dec 6, 2015, at 8:33 AM, inbox only via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

True,even that a feature isn't used doesn't mean that you need to remove that feature.
I hope that the proposal will be rejected.

2015-12-06 12:03 GMT+02:00 Clemens Wagner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:
> We’ve developed a number of Swift apps for various clients over the past year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like C-loops and increment or decrement operators of a programming language. How about the developers and the productive code which used C-style loops already?

I understand the reasons why you, Erica and the others don’t like C-style loops. But changing the philosophy of a productive programming language is a very bad idea.

Cheers
Clemens
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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

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

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


(Erica Sadun) #16

A slightly updated proposal write-up with everyone's feedback: https://gist.github.com/erica/56d533b75d0a36e3908f

···

On Dec 6, 2015, at 2:13 PM, Tyler Fleming Cloutier <cloutiertyler@aol.com> wrote:

Lowered Readability and Maintainability

I have aesthetic reasons for disliking the for-loop. The C-style loop is harder to read especially for those not coming from C-style languages, easier to mess up at edge conditions, and is commonly used for side-effects which, in a language focused on safety, is not a feature to be encouraged.

For example, one side effect that was mentioned on-list yesterday was the incrementor, which is guaranteed in C-style to execute late:
Roland King writes:

for var floatingThing = start ; floatingThing <= end ; floatingThing += delta
{
  // more than a few lines of code with early escape continues
}

shows intent of the loop very clearly, start, condition and increment all together at the top, and however you loop you always execute the increment part of the statement. Convert that to a while(), if you have a continue in the body, you have a good chance of not incrementing at all, or duplicating the increment code before every continue. So you can’t always nicely turn for into while. I second the point below about the loop variable being local to the for as well, I also like that.

Late incrementor management is a feature that can be mimicked with defer, as pointed out by several other list members.

Defer wouldn’t accomplish the exact same behavior because it would run if an exception was thrown, which is not the same as the last clause of a for loop, but perhaps is close enough.

The only other concern I would have is not being able to scope my variables to the loop. I didn’t see it addressed, but perhaps its not very important in the end anyway.

Something like the following might be nice to scope the variable exclusively to the loop.

for var x = 0 while (someCondition()) {
  // code
}


(Liam Butler-Lawrence) #17

I’m going to add a +1 for Erica’s proposal. Here’s why:

1. For every situation in which the for loop could be used, a for…in (either with ranges or strides) or while loop could achieve the same goals.

2. For the vast majority of these cases, the for…in or while version is much cleaner and easier to read than for(init;test;inc). More extensive refactoring might be necessary in some cases, but in my opinion that effort would be worthwhile to improve readability and consistency.

3. For new programmers learning the language, the for…in is much easier to learn. To my understanding, this is a major goal of Swift. For those coming to Swift that have some experience with other languages, we should be guiding them towards the optimal Swift way of doing things. Letting those programmers use an inelegant, legacy feature “just because” does not seem to me to fit the goals of Swift. In addition, the for…in loop is not even a new Swift concept; many languages (including C++, and Objective-C, and Python) already have for..in style loops available.

4. To the comment that said "even that a feature isn't used doesn't mean that you need to remove that feature": I don’t agree. If a given feature is inferior to its alternatives and is not actually in common use, why not simplify the language and just remove it? I think many of us would agree that for(init;test;inc) loops fail the smell test we should be using: would we add this in Swift 3 if it didn’t already exist?

Lastly, I’d like to point out that I, too, had a knee-jerk negative reaction when I saw the already accepted proposal for removing ++ and --. After reading the rationale and discussion regarding that change, I completely changed my mind. I believe this proposal should accepted for similar reasons.

Thanks,
Liam

···

On Dec 6, 2015, at 10:33 AM, inbox only via swift-evolution <swift-evolution@swift.org> wrote:

True,even that a feature isn't used doesn't mean that you need to remove that feature.
I hope that the proposal will be rejected.

2015-12-06 12:03 GMT+02:00 Clemens Wagner via swift-evolution <swift-evolution@swift.org>:

> We’ve developed a number of Swift apps for various clients over the past year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like C-loops and increment or decrement operators of a programming language. How about the developers and the productive code which used C-style loops already?

I understand the reasons why you, Erica and the others don’t like C-style loops. But changing the philosophy of a productive programming language is a very bad idea.

Cheers
Clemens
_______________________________________________
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


(Sean Heber) #18

This is the exact scenario that lead to my own code base having a few cases of C-style (all of which I've now trivially removed). Even so, I do not believe it is worth keeping it around for this reason.

l8r
Sean

···

On Dec 6, 2015, at 2:37 PM, Michel Fortin via swift-evolution <swift-evolution@swift.org> wrote:

There is actually one good reason I see in favor of keeping the C-style for loop, and only one: ease of porting existing code to Swift.

If you are porting code from another language that uses C-style for loops, currently you can keep the loop as is while you translate all the syntactic differences everywhere. If Swift didn't had a C-style for loop, then you'd need to rethink the control flow at the same time you are converting everything else, increasing the risk of errors during what is already a delicate operation.

C-style for loops are very common in code you can find everywhere because many languages have it, and therefore there is a lot of algorithms, sometime tricky algorithms you don't want to mess up, that rely on such loops. Even if you had the desire to convert all of them to for-in loops in your port, rewriting the control flow *at the same time* you are addressing all the other porting issues is much worse than doing it in a separate step *after* the crude port has been tested to work.

In other words: you should avoid refactoring everything in one step. The C-style for loop enables that.

--
Michel Fortin
michel.fortin@michelf.ca
https://michelf.ca

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


(Clemens Wagner) #19

I think removing the increment and decrement operators is just another bad idea. They are well known and frequently used by many developers. But discussing an approved proposal would be pointless. :frowning: In my opinion Swift will be unusable if fundamental features will change every year. Some kind of stability in the language would be highly appreciated by Swift users.

Clemens

···

Am 06.12.2015 um 17:31 schrieb David Waite via swift-evolution <swift-evolution@swift.org>:

Nearly every for loop I’ve written in other languages has used pre or post increment (depending on the language), which is being removed in Swift 3.0. It makes sense for 'for loops' to go if pre/post increment goes away.

-DW

On Dec 6, 2015, at 9:03 AM, Don Wills via swift-evolution <swift-evolution@swift.org> wrote:

I too hope that the proposal to remove C-style loops is rejected. Yes, they aren't that necessary any more, but if we want Swift to compete with Java, C#, C++ and C, there is no reason to remove basic features like C-style loops just because they are politically incorrect. If there was a functional reason, I might get on board with removing it, but there isn't.

I also hope that the decision to remove increment and decrement operators is reversed using the same logic. Just because *you* don't like something that has been a feature of dozens of programming languages for 40 years doesn't mean removing that feature is a good idea. One man's goto statement is another man's Leatherman multi-tool. And FWIW, if C-style loops stay in the language, they become much more ugly without increment and decrement.

Don Wills

On Dec 6, 2015, at 8:33 AM, inbox only via swift-evolution <swift-evolution@swift.org> wrote:

True,even that a feature isn't used doesn't mean that you need to remove that feature.
I hope that the proposal will be rejected.

2015-12-06 12:03 GMT+02:00 Clemens Wagner via swift-evolution <swift-evolution@swift.org>:
> We’ve developed a number of Swift apps for various clients over the past year and have not needed C style for loops either.

But I think this is a very weak reason for *removing* any portion like C-loops and increment or decrement operators of a programming language. How about the developers and the productive code which used C-style loops already?

I understand the reasons why you, Erica and the others don’t like C-style loops. But changing the philosophy of a productive programming language is a very bad idea.

Cheers
Clemens
_______________________________________________
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


(Paul Cantrell) #20

People can do the (usually) trivial transformation to a while loop first. The cases where loop exits make the transformation nontrivial seem rare to me.

Doing a port of C, C++, Java, or C# code to Swift, that for→while transformation seems trivial next to, say, dealing with the differences in Swift’s type system, its memory management, or its handling of unsafe pointers — all things one would have to deal with in the first pass of a port.

I’m not sure easy porting from C is even a design consideration, but even if it is, it shouldn’t be a reason to hold back this proposal.

Cheers, P

···

On Dec 6, 2015, at 2:37 PM, Michel Fortin via swift-evolution <swift-evolution@swift.org> wrote:

There is actually one good reason I see in favor of keeping the C-style for loop, and only one: ease of porting existing code to Swift.

If you are porting code from another language that uses C-style for loops, currently you can keep the loop as is while you translate all the syntactic differences everywhere. If Swift didn't had a C-style for loop, then you'd need to rethink the control flow at the same time you are converting everything else, increasing the risk of errors during what is already a delicate operation.

C-style for loops are very common in code you can find everywhere because many languages have it, and therefore there is a lot of algorithms, sometime tricky algorithms you don't want to mess up, that rely on such loops. Even if you had the desire to convert all of them to for-in loops in your port, rewriting the control flow *at the same time* you are addressing all the other porting issues is much worse than doing it in a separate step *after* the crude port has been tested to work.

In other words: you should avoid refactoring everything in one step. The C-style for loop enables that.

--
Michel Fortin
michel.fortin@michelf.ca
https://michelf.ca

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