On Thu, 10 May 2018 15:02:39 -0000 Michael Jones <michael.jo...@gmail.com> wrote: > > Maybe the central issue here has been lost because of the confusion between > English words and the keywords of various languages. Let's be explicit: *a > controlled looping construct may test the control condition before or after > the iterated body of code. Go's 'for' tests before and and Go does not > provide keyword means to specify the test happen after.* > > Not a crisis, everyone works around this, but, the workaround is a > workaround. Language shapes thought. Languages that express test-after in > their vocabulary embrace code and data structuring that depend on it. > People who know such languages (such as C and others) will miss it. In 800 > AD Charlemagne said, "To have a second language is to have a second soul." > Same for computer languages.
Rather than add simple syntatic sugar like "while" or "until", it would make more sense to add a more powrrful & generalized loop syntax. Motivating example: If you want to iterate through two slices at the same rate, the "for" syntax doesn't generalize well. You have to do for i, v := range slice1 { if i >= len(slice2) { break; } u := slice2[i] .... } This loses the similarity in the way v & u take successive values from slice1 and slice2. Basically Go's for takes the first step from "for i := 0; i < N; i++ { ... }" but then stops. A generalized loop can clearly bring out the similarity: Example1: loop for v := range slice1 for u := range slice2 { ... } This iterates through both slices and exits when either range is exhausted. It can be more powerful by adding filtering, value generation and exit tests as loop phrases. Example2: loop for v := range slice while v != 10 { ... } This ends as soon as v becomes 10. Example3: loop for v := range slice until v != 10 { ... } Here the "until" test is done at the end of the loop (so the body will be executed with v == 10 *once* but not for any further values from slice). Example4: loop for x := range slice for y := 2*iota+1 // y takes values 1, 3, 5, ... ... } Here an expression around Go's wonderful "iota" is used to generate successive values. The loop ends once the slice range is exhausted. Example5: loop for x := 2*iota+1 // x takes values 1, 3, 5, ... if IsPrime(x) while x < 100 { ... } Here the loop body is executed for only prime valued x and terminates when x becomes > 100. "range slice" in effect is a generator. In a sense so is "iota". If we allow use of a generator function in a loop phrase, things get more interesting. Example6: // primegen returns a prime generator function func primegen() func() int { p := 2 return func() int { for { q := p if p == 2 { p += 1} else { p += 2 } if IsPrime(q) { return q } } } } prime := primegen() loop for x := prime() for y := iota while y < 100 { fmt.Println(x) } Here primegen() returns a new function that returns successive primes every time it is called. The loop prints out first 100 primes. This generalized loop should translate in a straightforward way to go1 style "for" loop code. Credit: Common Lisp's LOOP macro. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.