[swift-evolution] A (better) Swift Equivalent For The Classical For-Loop With Numeric Scalars

ted van gaalen tedvgiosdev at gmail.com
Mon Mar 21 11:05:26 CDT 2016

Hello Taras
Please take a look here:

More than 30  !  programming languages since 1957 until now, have their implementation of the for-loop. If it was or is an inferior construct, it would have disappeared long ago. That alone proves that it is not inferior, but indeed very useful.

There is imho no longer any need to compare the for... variants any longer (but of course feel free to do so), because they both serve different purposes very well. Neither one or the other is inferior! I would protest with equal energy also when the for...in... was removed, because this would make iterating with collections cumbersome, e.g. I am now very happy that I can now iterate through an array, without specifying start, length and where we are.. 

Concerning my intended proposal for a good alternative for the classicsl for-loop, I am currently in favor of very much something like this version, as it is implemented in Maple:
  -----------start copy from wkpd page-----------------------------------
> Maple has two forms of for-loop, one for iterating of a range of values, and the other for iterating over the contents of a container. The value range form is as follows:
> for i from f by b to t while w do # loop body od;
> All parts except do and od are optional. The for i part, if present, must come first. The remaining parts (from f, by b, to t, while w) can appear in any order.
> Iterating over a container is done using this form of loop:
> for e in c while w do # loop body od;
> The in c clause specifies the container, which may be a list, set, sum, product, unevaluated function, array, or an object implementing an iterator.
> A for-loop may be terminated by od, end, or end do.
------------------------------end copy-------------------------------------------

( in the above example replace "do" and "od" by { } )
Maple has two forms of for-loop, one for iterating of a range of values, 
and the other for iterating over the contents of a container.
In Maple, which by the way is a very advanced programming language for mathematicians ( i am not), both variants are available and co-exist independently, which is exactly my point!  So again, it is not replacing or even changing the for-in as it is now available in Swift, both versions should be available. (This would still be the case if the for ;; had not been removed in the first place)
To get back to the Maple for-loop implementation, in Swift I'd drop the "while" extension.
To summarize:

I would like to see in Swift:

     for v from v1 to v2 by v3  {...}

for numerical values Int, Double, Float...
The "by" clause would be optional: when omitted, it should
default to 1 for integers and 1.0 for floating point values.
The loop variable ("v" here) cannot be altered in the loop.
The loop can exited with the "break" statement.
Use "continue" to directly go to the next iteration( if any)
("break" and "continue" functional as it is now)

     for v from 0.5 to 30.0 by 0.3 
     for v from 0 to 100 by 5
     for v from 12.0 to -10.0 by -2

Imho, this is super clean and very readable, Why would anyone have objections against it? Also the compiler can optimize this construct very easely. 
Yes, the classical for ;; had more options, but are they still needed? 

Note that we also have discussed the floating point number tolerance problem previously. 
the for ... from ... to ... by ... could therefore for floating point numbers perhaps be enhanced like so:

     for v from 0.0 to 10.0 by 0.1 tolerance 0.01     // tolerance optional clause

so that it reaches the end value 10.0 in this case

(I am not in favor to automatically set tolerance based upon magnitude)

To summarize:

1. the existing for ... in ...  which is nearly perfect for collections can remain as is. No conflicts here. There is no need to drop one for the other, they are completely independent. 

2. The new for ... from ... to ... by ... is simple,straightforward and easy to implement.

You've mentioned this:
> for (i,j,k) in matrix.indices {...}

but here we are working with collection (descendants), are we?

I'd kindly recommend us all to travel much to other programming worlds, because there are so many (often forgotten) very interesting aspects and ideas that can be very useful to implement in new languages.

Kind Regards

> On 21 Mar 2016, at 14:30, Taras Zakharko <taras.zakharko at uzh.ch> wrote:
> To be honest, I have difficulty understanding the premise of this discussion. I have always found the C-style  for(;;) loop an awkward construct, because it is essentially just an alternative form of writing a general-purpose while loop.  It is perfectly reasonable to restrict the for construct to, well, ‘for’ contexts: iterating through a sequence of items. If you need something more complex, either write your own iterator or use a general-purpose while loop.  
> As discussed previously, an optimising compiler generates the same machine code whether you are using an iterator abstraction or low-level coding. Besides, the for .. in .. construct potentially offers more potential for optimisation, because it makes the counter variable as well as the semantics of the entire loop more explicit (a for(;;) can contain arbitrary stuff). Talking about numerical algorithms: this is something I can’t understand at all. I have been working with numerical algorithms in Python and R for years, and I have never ever missed the C-style for loop. These languages offer convenient functions for generating iterable sequences, which are more readable and also represent the loop  semantics much better then the for(;;;). Not to mention that the iterator pattern allows you to write simpler and more maintainable code. Imagine iterating through a sparse matrix or something. With a proper iterator pattern you just do:
> for (i,j,k) in matrix.indices {
> }
> With a for(;;) loop you’l probably end up writing a nested construct of quite some complexity. 
> Swift could certainly use some improvements to its iterators (for example something like Python generator expressions might be useful), but that is a different topic.  
> To sum it up:
> - for(;;) is an awkward construct which is closer to a while loop than an actual sequence iterator pattern (that it should be)
> - a proper iterator pattern is more convenient, more readable and offers the same performance
> - numerical code does not need a for(;;) construct, in fact, using the proper iterator pattern makes writing numeric code easier, not more difficult, because you can abstract away some common processing/aggregating steps easily, and without any drawback
> - we should think about how to improve the iterators offered by Swift standard library, not go back to an inferior construction
> — Taras
>>> On 21 Mar 2016, at 12:37, Greg Parker via swift-evolution <swift-evolution at swift.org> wrote:
>>> On Mar 19, 2016, at 12:46 AM, Dmitri Gribenko via swift-evolution <swift-evolution at swift.org> wrote:
>>> Hi Ted,
>>> Thank you for starting this thread.  I agree that removing the C-style
>>> for loop has degraded the readability and clarity of some of numerics
>>> code.
>>> In the feedback to SE-0007 many people have said that they can convert
>>> their code to for-in loops, but I think this actually means that in
>>> code that is typically written in Swift today, loops primarily operate
>>> on sequences and collections.  It means that numerics is a domain that
>>> not many people work in.  But it is a very important domain
>>> nevertheless, and clarity for numerics code matters at least as much
>>> as it does everywhere else.
>>> I think one way to approach this discussion would be to present
>>> multiple concrete code samples that contain C-style for loops and are
>>> awkward to write without them.  We can then try looking for patterns,
>>> generalize and simplify, and discuss possible solutions.
>> Let me emphasize this more strongly. *Concrete*, *real-world* examples are quite likely the only way that you are going to get `for(;;)` back or get any sort of semantically-similar syntactically-different replacement.
>> There have been lots of suggestions. None of them are perfect. If we assume that there is in fact no perfect solution then the only way to proceed is to provide sufficient justification for some imperfect solution.
>> I'm still waiting for something like this: "We ported our code to Swift 3. Here are 5 reasonable-looking for(;;) loop shapes from 150 call sites, and here are their ugly-looking rewrites."
>> (Personally I think removing for(;;) without direct replacement was too aggressive. That view lost. Now its advocates will need to do more work to upend the status quo.)
>> -- 
>> Greg Parker     gparker at apple.com     Runtime Wrangler
>> _______________________________________________
>> 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/20160321/4f4a87b6/attachment.html>

More information about the swift-evolution mailing list