[Proposal] Add keyword "by" as syntactic sugar to streamline For-In-loop


(Hans Huck) #1

Rationale:

Swift’s For-In-loop is fine, as long as you don’t need an iteration step size other than 1/-1, in which case it becomes unexpectedly inconsistent and unwieldy.

for i in 1…10

for i in reverse(10…1)

for i in stride(from:1, through:10, by:3)

or even

for i in 1.stride(through:10, by:3)

The above sequence is not only confusing for teaching purposes/beginners (first lesson: protocols. really?), but also unnecessarily bulky for everyday use. It’s a For-loop, one of the most basic and frequently used structures in any language – please let’s make it pithy.

Comparison:

Currently, even the C-style For-loop we are just about to get rid of could be argued to be more concise and consistent, but significantly more so are the likes of

Python

for i in range(1, 10, 3):

– Lua

for i = 1, 10, 3

’ Basic

for i = 1 to 10 step 3

(* Modula-2 *)

for i := 1 to 10 by 3

// Chapel

for i in 1…10 by 3

or any other remotely relevant non-C-style language that allows For-loops with an altered step size.

While there are other issues like having to use reverse(1…10) instead of simply 10…1, (which compiles, but doesn’t run, even when using literals – why?) none of it goes against the grain as much as being forced to type out stride(boiboiboilerplate) for a simple iteration.

Suggestion(s):

A) Add keyword “by” as syntactic sugar, used as in Modula/Chapel (and tip our hat to Algol 68):

// Swift

for i in 1…10 by 3

for i in reverse(1…10) by -3

or even better yet (if feasible):

B)

for i in 1…10 by 3

for i in 10…1 by -3

Please comment, and thanks everyone for reading.

– Hans


(Erica Sadun) #2

You may want to take a peek here: https://gist.github.com/erica/a51a981ee0352235204692affa959307

-- E

···

On Apr 13, 2016, at 8:52 AM, Hans Huck via swift-evolution <swift-evolution@swift.org> wrote:

Rationale:

Swift's For-In-loop is fine, as long as you don't need an iteration step size other than 1/-1, in which case it becomes unexpectedly inconsistent and unwieldy.

for i in 1...10
for i in reverse(10...1)
for i in stride(from:1, through:10, by:3)
or even
for i in 1.stride(through:10, by:3)

The above sequence is not only confusing for teaching purposes/beginners (first lesson: protocols. really?), but also unnecessarily bulky for everyday use. It's a For-loop, one of the most basic and frequently used structures in any language -- please let's make it pithy.

Comparison:

Currently, even the C-style For-loop we are just about to get rid of could be argued to be more concise and consistent, but significantly more so are the likes of

# Python
for i in range(1, 10, 3):

-- Lua
for i = 1, 10, 3

' Basic
for i = 1 to 10 step 3

(* Modula-2 *)
for i := 1 to 10 by 3

// Chapel
for i in 1..10 by 3

or any other remotely relevant non-C-style language that allows For-loops with an altered step size.

While there are other issues like having to use reverse(1...10) instead of simply 10...1, (which compiles, but doesn't run, even when using literals -- why?) none of it goes against the grain as much as being forced to type out stride(boiboiboilerplate) for a simple iteration.

Suggestion(s):

A) Add keyword "by" as syntactic sugar, used as in Modula/Chapel (and tip our hat to Algol 68):

// Swift
for i in 1...10 by 3
for i in reverse(1...10) by -3

or even better yet (if feasible):

B)
for i in 1...10 by 3
for i in 10...1 by -3

Please comment, and thanks everyone for reading.

-- Hans

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


(Vladimir) #3

as @Erica just noted, we probably will have this in Swift3 :

for i in (1...10).striding(by: 3) {..}
for i in (1...10).striding(by: -3) {..}

But.. compare how the next is more clear and nice looking, has less noise, how faster this will be typed.. :

for i in 1...10 by 3 {...}
for i in 1...10 by -3 {...}

just beautiful :slight_smile:
My opinion: this .striding is about Range type. Range type is used in many places, not just in for-in loop. It is important to have handy and clear methods for Range. But. If we are talking about loop - why(why?) can't we have such a great syntax for such a common loop task? It is explicit, it can generate the same (1...10).striding(by: 3) code internally.
IMO I'd love to have such syntax in Swift for for-in loop

···

On 13.04.2016 17:52, Hans Huck via swift-evolution wrote:

Rationale:
Swift's For-In-loop is fine, as long as you don't need an iteration step
size other than 1/-1, in which case it becomes unexpectedly inconsistent
and unwieldy.
for i in 1...10
for i in reverse(10...1)
for i in stride(from:1, through:10, by:3)
or even
for i in 1.stride(through:10, by:3)
The above sequence is not only confusing for teaching purposes/beginners
(first lesson: protocols. really?), but also unnecessarily bulky for
everyday use. It's a For-loop, one of the most basic and frequently used
structures in any language -- please let's make it pithy.

Comparison:
Currently, even the C-style For-loop we are just about to get rid of could
be argued to be more concise and consistent, but significantly more so are
the likes of
# Python
for i in range(1, 10, 3):
-- Lua
for i = 1, 10, 3
' Basic
for i = 1 to 10 step 3
(* Modula-2 *)
for i := 1 to 10 by 3
// Chapel
for i in 1..10 by 3
or any other remotely relevant non-C-style language that allows For-loops
with an altered step size.
While there are other issues like having to use reverse(1...10) instead of
simply 10...1, (which compiles, but doesn't run, even when using literals
-- why?) none of it goes against the grain as much as being forced to type
out stride(boiboiboilerplate) for a simple iteration.

Suggestion(s):
A) Add keyword "by" as syntactic sugar, used as in Modula/Chapel (and tip
our hat to Algol 68):
// Swift
for i in 1...10 by 3
for i in reverse(1...10) by -3
or even better yet (if feasible):
B)
for i in 1...10 by 3
for i in 10...1 by -3

Please comment, and thanks everyone for reading.
-- Hans

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


(Hans Huck) #4

You may want to take a peek here: https://gist.github.com/erica/a51a981ee0352235204692affa959307

-- E

Thanks for the link, Erica, very informative. The striding(by:) method combined with the (as of yet) non-canonical range types looks great; it also tackles half the problem, since it makes the use of reverse() no longer required in For-loops.

However, my main point remains unresolved, because

for i in (1...10).striding(by: -3)

is simply not as concise, readable, intuitive or elegant as

for i in 1...10 by -3

The "by" keyword is specifically meant to be syntactic sugar for the For-In-loop, and, as Vladimir pointed out, can easily be mapped onto the new striding() construct internally.

-- Hans