Observation: this discussion is very close to the debate around operator
overloading. In fact, if we add generics to the language, we could
define interfaces (I will use Alan Fox's square bracket syntax, as I
think it improves readability):

type Iterator[type Elem] interface {
    Next() bool
    Current() Elem
}

type Iterable[type Elem] interface {
    Iter() Iterator[Elem]
}

Then, generic iterator code could look like:

    for it := collection.Iter(); it.Next(); {
        cur := it.Current()
        // ...
    }

In this case, allowing range to be used with user-defined collections is
more-or-less a special case of operator overloading.

I'm not making a value judgement here, just an observation. The
arguments for and against I think are almost 1-to-1.

Quoting 'Axel Wagner' via golang-nuts (2018-10-22 15:20:37)
>    There's also the additional objection that this doesn't play well with
>    break/return - if the iterator needs to do some cleanup (say, closing a
>    file or something). IMO, these days, just use bufio.Scanner-like
>    iterators or just a channel+context, if syntax is that important to
>    you. But personally I don't see the point of introducing a custom
>    iterator concept just to *occasionally* save one or two lines of code.
>
>    On Mon, Oct 22, 2018 at 7:16 PM Eric S. Raymond <[1]e...@thyrsus.com>
>    wrote:
>
>      David Anderson <[2]d...@natulte.net>:
>      > [3]https://github.com/golang/go/issues/13027 is a past proposal to
>      allow the
>      > `range` operation to work on arbitrary types (although it was
>      originally
>      > proposed as a narrow enhancement on container/list only). Didn't
>      get very
>      > far, but sprinkled in the bug are some of the objections a new
>      proposal
>      > would want to address.
>      Read it.�  Not thought through very well, alas. Rightly rejected.
>      > The big one for me personally is the argument for readability:
>      currently,
>      > Go code doesn't contain surprising execution: if there's not a
>      function
>      > call, you can reasonably expect that there's no hidden computation
>      > happening. Python-style iterators and generators specifically go
>      against
>      > that, in that a simple looking range statement might run
>      arbitrarily
>      > complex code between loop iterations, rather than just increment a
>      pointer.
>      That is a reasonable objection.�  But there is potentially a *much*
>      simpler way to specify an iterator that actually *uses* a function
>      call, properly cluing the reader in that something
>      function-call-like
>      is going on.�  And doesn't require a special iterator construct tied
>      to classes, meeting Griesemer's objection.
>      In my real-world case, I want an iterator so I can walk through a
>      list
>      of hundreds of thousands of items selecting those of interest
>      without
>      having to construct the entire list of selectees.�  I'm mulling over
>      a
>      couple of alternative variations, but the core idea is to give range
>      new semantics when it's passed an expression of *function* type
>      Suppose you see this:
>      for i, commit:= range IteratorFactory(MyStupidlyLongEventList,
>      "commits") {
>      �  �  �  �  DoStuffWith(commit)
>      }
>      The concept is that the first thing the loop does is call
>      IteratorFactory(),
>      which returns not a list but a *closure*.�  The loop then evaluates
>      the closure
>      repeatedly, binding its return value to commit and running the loop
>      body, until
>      the closure return tells the loop to terminate,
>      This meets the discoverability objection. The function call is your
>      clue that to understand he loop you need to look at the return value
>      of
>      IteractorFactory, which could have been a list or map or channel
>      before
>      my proposal and could after it be a closure.
>      (I think it's a little oversimplifying to claim that the current
>      semantics
>      is as simple as a pointer bump, especially with respect to
>      channels.)
>      The detail in which the devil lurks is how the closure returns a
>      stop value.
>      There are a couple of different ways this could work; I'll write an
>      RFE
>      once I figure out which is the Right Thing.
>      --
>      �  �  �  �  �  �  �  �  <a href="[4]http://www.catb.org/~esr/";>Eric
>      S. Raymond</a>
>      My work is funded by the Internet Civil Engineering Institute:
>      [5]https://icei.org
>      Please visit their site and donate: the civilization you save might
>      be your own.
>      --
>      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 [6]golang-nuts+unsubscr...@googlegroups.com.
>      For more options, visit [7]https://groups.google.com/d/optout.
>
>    --
>    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 [8]golang-nuts+unsubscr...@googlegroups.com.
>    For more options, visit [9]https://groups.google.com/d/optout.
>
> Verweise
>
>    1. mailto:e...@thyrsus.com
>    2. mailto:d...@natulte.net
>    3. https://github.com/golang/go/issues/13027
>    4. http://www.catb.org/~esr/
>    5. https://icei.org/
>    6. mailto:golang-nuts%2bunsubscr...@googlegroups.com
>    7. https://groups.google.com/d/optout
>    8. mailto:golang-nuts+unsubscr...@googlegroups.com
>    9. https://groups.google.com/d/optout

-- 
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.

Reply via email to