Comment on PEP-0322: Reverse Iteration Methods

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Stephen Horne

    #46
    Re: Comment on PEP-0322: Reverse Iteration Methods

    On Sat, 27 Sep 2003 15:22:37 GMT, Alex Martelli <aleax@aleax.it >
    wrote:
    [color=blue]
    >David Abrahams wrote:
    > ...[color=green]
    >> Well, (understanding that you don't nececessarily agree with the
    >> above) you can in fact iterate on std::pair<T,T> with the usual C++
    >> iterator protocol,[/color]
    >
    >You mean there's an std::pair::begi n etc?! OK, I guess I'm even
    >rustier on standard C++ than I thought I was -- I could have SWORN
    >there wasn't. (Std chapter & verse pls? I plan to win bets based
    >on this tidbit...!-). So I guess the lack of those in gcc is a
    >breach of the Standard on gcc's part...?[/color]

    Somehow I think David is mistaken here - I cannot believe that
    dereferencing an iterator returns a different datatype depending on
    which item it happens to point to at runtime in statically typed C++,
    and without that ability to dereference the iterator (1) I cannot see
    the point of iterating through a pair, and (2) the 'iterator' would
    not be a true iterator as C++ iterators have to comply with one of a
    set of standard protocols (forward, bidirectional, random etc) which
    all include subscripting.

    Of course you can iterate through a container that holds std::pair
    objects - you do that every time you iterate through an std::map - but
    that isn't the same thing.


    --
    Steve Horne

    steve at ninereeds dot fsnet dot co dot uk

    Comment

    • Stephen Horne

      #47
      Re: Comment on PEP-0322: Reverse Iteration Methods

      On Sat, 27 Sep 2003 16:35:10 +0100, Stephen Horne
      <$$$$$$$$$$$$$$ $$$@$$$$$$$$$$$ $$$$$$$$$.co.uk > wrote:
      [color=blue]
      >set of standard protocols (forward, bidirectional, random etc) which
      >all include subscripting.[/color]

      Oops - I've got subscripting on the mind just now. I meant
      dereferencing of course.


      --
      Steve Horne

      steve at ninereeds dot fsnet dot co dot uk

      Comment

      • David Abrahams

        #48
        Re: Comment on PEP-0322: Reverse Iteration Methods

        Alex Martelli <aleax@aleax.it > writes:
        [color=blue]
        > David Abrahams wrote:
        > ...[color=green]
        >> Well, (understanding that you don't nececessarily agree with the
        >> above) you can in fact iterate on std::pair<T,T> with the usual C++
        >> iterator protocol,[/color]
        >
        > You mean there's an std::pair::begi n etc?![/color]

        No, that's an entirely different question. I can build an iterator
        which iterates over pair<T,T>.
        [color=blue]
        > OK, I guess I'm even rustier on standard C++ than I thought I was --
        > I could have SWORN there wasn't. (Std chapter & verse pls? I plan
        > to win bets based on this tidbit...!-). So I guess the lack of
        > those in gcc is a breach of the Standard on gcc's part...?[/color]

        No, nothing like that.
        [color=blue][color=green]
        >> and with a new mixed compile-time/runtime tuple iterator protocol
        >> developed by Doug Gregor, iteration over heterogeneous tuples is
        >> possible too. It certainly is desirable to be able to do that;
        >> it's a real need that has come up in practice.[/color]
        >
        > So, given an arbitrary struct, with fields (generally) of different
        > types, you can iterate field by field?[/color]

        Ah, no. A tuple in C++ is a different thing, and much more like a
        Python tuple: http://www.boost.org/libs/tuple
        [color=blue]
        > That's basically what the "heterogene ous tuple" is supposed to be
        > equivalent to, in the "party line" I was relating[/color]

        Well, that's just nutty. We can make a much better analogy to a
        struct in Python with the usual class hacks. But even then, we can
        arrange to iterate the attributes.
        [color=blue]
        > (although the names to go with the fields are only present in a FEW
        > such tuples, such as those returned by modules time and stat,[/color]

        Whaa?? Are they subclassing tuple? Nope, time.struct_tim e is not
        even a tuple. It's just the struct hack with a tuple-like repr()
        [color=blue][color=green][color=darkred]
        >>> time.localtime( )[/color][/color][/color]
        (2003, 9, 27, 12, 10, 43, 5, 270, 1)[color=blue][color=green][color=darkred]
        >>> type(time.local time())[/color][/color][/color]
        <type 'time.struct_ti me'>[color=blue][color=green][color=darkred]
        >>> time.struct_tim e.__bases__[/color][/color][/color]
        (<type 'object'>,)
        [color=blue]
        > as of now; more general tuples still haven't grown the ability to
        > access fields by name, in Python).
        >
        > My partial dissent comes from feeling the need for "frozen/immutable
        > lists" and the fact that tuples are often used as such (including goofy
        > immutable representations of dicts, e.g. via tuple(thedict.i teritems()),
        > and the like). If tuples cannot be thought of as immutable lists, then
        > (I think) we need "immutable/hashable/frozen" lists by other means.[/color]

        I agree completely.
        [color=blue]
        > (I need to say "I think" because, as I quoted, Ruby experts claim that
        > the "anyobject.free ze" feature they do have isn't actually as useful
        > as it SEEMS it should be -- though I'm not sure I understand why, yet).[/color]

        Immutability is extremely useful whenever you have inplace operations
        like +=, because it guarantees value stability for other references
        to the same object.

        --
        Dave Abrahams
        Boost Consulting

        Comment

        • David Abrahams

          #49
          Re: Comment on PEP-0322: Reverse Iteration Methods

          Stephen Horne <$$$$$$$$$$$$$$ $$$@$$$$$$$$$$$ $$$$$$$$$.co.uk > writes:
          [color=blue]
          > On Sat, 27 Sep 2003 15:22:37 GMT, Alex Martelli <aleax@aleax.it >
          > wrote:
          >[color=green]
          >>David Abrahams wrote:
          >> ...[color=darkred]
          >>> Well, (understanding that you don't nececessarily agree with the
          >>> above) you can in fact iterate on std::pair<T,T> with the usual C++
          >>> iterator protocol,[/color]
          >>
          >>You mean there's an std::pair::begi n etc?! OK, I guess I'm even
          >>rustier on standard C++ than I thought I was -- I could have SWORN
          >>there wasn't. (Std chapter & verse pls? I plan to win bets based
          >>on this tidbit...!-). So I guess the lack of those in gcc is a
          >>breach of the Standard on gcc's part...?[/color]
          >
          > Somehow I think David is mistaken here - I cannot believe that
          > dereferencing an iterator returns a different datatype depending on
          > which item it happens to point to at runtime in statically typed
          > C++,[/color]

          You didn't read carefully enough: I said std::pair<T,T>, not
          std::pair<T,U>.
          [color=blue]
          > and without that ability to dereference the iterator (1) I cannot see
          > the point of iterating through a pair, and (2) the 'iterator' would
          > not be a true iterator as C++ iterators have to comply with one of a
          > set of standard protocols (forward, bidirectional, random etc) which
          > all include subscripting.[/color]

          I'm pretty well familiar with those protocols - I've been working on
          the C++ standards committee since 1997 and have written several
          related proposals, c.f. http://tinyurl.com/ovpe.
          [color=blue]
          > Of course you can iterate through a container that holds std::pair
          > objects - you do that every time you iterate through an std::map - but
          > that isn't the same thing.[/color]

          No, definitely not.

          --
          Dave Abrahams
          Boost Consulting

          Comment

          • John Roth

            #50
            Re: Comment on PEP-0322: Reverse Iteration Methods


            "David Abrahams" <dave@boost-consulting.com> wrote in message
            news:ullsa5hui. fsf@boost-consulting.com. ..[color=blue]
            > Alex Martelli <aleax@aleax.it > writes:[color=green]
            > >
            > > So, given an arbitrary struct, with fields (generally) of different
            > > types, you can iterate field by field?[/color]
            >
            > Ah, no. A tuple in C++ is a different thing, and much more like a
            > Python tuple: http://www.boost.org/libs/tuple
            >[color=green]
            > > That's basically what the "heterogene ous tuple" is supposed to be
            > > equivalent to, in the "party line" I was relating[/color]
            >
            > Well, that's just nutty. We can make a much better analogy to a
            > struct in Python with the usual class hacks. But even then, we can
            > arrange to iterate the attributes.
            >[color=green]
            > > (although the names to go with the fields are only present in a FEW
            > > such tuples, such as those returned by modules time and stat,[/color]
            >
            > Whaa?? Are they subclassing tuple? Nope, time.struct_tim e is not
            > even a tuple. It's just the struct hack with a tuple-like repr()
            >[color=green][color=darkred]
            > >>> time.localtime( )[/color][/color]
            > (2003, 9, 27, 12, 10, 43, 5, 270, 1)[color=green][color=darkred]
            > >>> type(time.local time())[/color][/color]
            > <type 'time.struct_ti me'>[color=green][color=darkred]
            > >>> time.struct_tim e.__bases__[/color][/color]
            > (<type 'object'>,)[/color]

            Not exactly. It's an object that can be subscripted like a
            sequence, so it looks like a tuple for the most common
            use cases. I haven't looked at the code, so I don't
            know how far they went in putting in the remainder of
            tuple behavior, though.

            The subscripting and slicing is the key point here, though.
            That's what makes it backward compatible. It's not an
            extended tuple, and I doubt if it has most of the tuple
            methods.

            Frankly, I prefer to call it a data object, rather than
            a "struct hack." Calling it a data object means that
            it might grow other useful behaviors in the future. I'm
            not sure about time, but I could appreciate methods
            in stat that apply the access and modify dates to another
            file in one operation.
            [color=blue]
            >[color=green]
            > > as of now; more general tuples still haven't grown the ability to
            > > access fields by name, in Python).[/color][/color]

            And they most likely won't. It's easy enough to create
            a data object that implements the basic part of the sequence
            protocol.

            John Roth
            [color=blue]
            >
            > --
            > Dave Abrahams
            > Boost Consulting
            > www.boost-consulting.com[/color]


            Comment

            • Stephen Horne

              #51
              Re: Comment on PEP-0322: Reverse Iteration Methods

              On Sat, 27 Sep 2003 12:17:53 -0400, David Abrahams
              <dave@boost-consulting.com> wrote:
              [color=blue]
              >Stephen Horne <$$$$$$$$$$$$$$ $$$@$$$$$$$$$$$ $$$$$$$$$.co.uk > writes:[/color]
              [color=blue][color=green]
              >> Somehow I think David is mistaken here - I cannot believe that
              >> dereferencing an iterator returns a different datatype depending on
              >> which item it happens to point to at runtime in statically typed
              >> C++,[/color]
              >
              >You didn't read carefully enough: I said std::pair<T,T>, not
              >std::pair<T,U> .
              >[color=green]
              >> and without that ability to dereference the iterator (1) I cannot see
              >> the point of iterating through a pair, and (2) the 'iterator' would
              >> not be a true iterator as C++ iterators have to comply with one of a
              >> set of standard protocols (forward, bidirectional, random etc) which
              >> all include subscripting.[/color]
              >
              >I'm pretty well familiar with those protocols - I've been working on
              >the C++ standards committee since 1997 and have written several
              >related proposals, c.f. http://tinyurl.com/ovpe.[/color]

              OK - sorry for that.

              I remain surprised that this degree of specialisation occurs, but it's
              a case of live and learn I suppose.


              --
              Steve Horne

              steve at ninereeds dot fsnet dot co dot uk

              Comment

              • David Abrahams

                #52
                Re: Comment on PEP-0322: Reverse Iteration Methods

                Stephen Horne <$$$$$$$$$$$$$$ $$$@$$$$$$$$$$$ $$$$$$$$$.co.uk > writes:
                [color=blue][color=green][color=darkred]
                >>> and without that ability to dereference the iterator (1) I cannot see
                >>> the point of iterating through a pair, and (2) the 'iterator' would
                >>> not be a true iterator as C++ iterators have to comply with one of a
                >>> set of standard protocols (forward, bidirectional, random etc) which
                >>> all include subscripting.[/color]
                >>
                >>I'm pretty well familiar with those protocols - I've been working on
                >>the C++ standards committee since 1997 and have written several
                >>related proposals, c.f. http://tinyurl.com/ovpe.[/color]
                >
                > OK - sorry for that.[/color]

                No prob.
                [color=blue]
                > I remain surprised that this degree of specialisation occurs, but
                > it's a case of live and learn I suppose.[/color]

                Sorry, what specialization?

                --
                Dave Abrahams
                Boost Consulting

                Comment

                • Stephen Horne

                  #53
                  Re: Comment on PEP-0322: Reverse Iteration Methods

                  On Sat, 27 Sep 2003 19:48:24 -0400, David Abrahams
                  <dave@boost-consulting.com> wrote:
                  [color=blue]
                  >Stephen Horne <$$$$$$$$$$$$$$ $$$@$$$$$$$$$$$ $$$$$$$$$.co.uk > writes:
                  >[color=green][color=darkred]
                  >>>> and without that ability to dereference the iterator (1) I cannot see
                  >>>> the point of iterating through a pair, and (2) the 'iterator' would
                  >>>> not be a true iterator as C++ iterators have to comply with one of a
                  >>>> set of standard protocols (forward, bidirectional, random etc) which
                  >>>> all include subscripting.
                  >>>
                  >>>I'm pretty well familiar with those protocols - I've been working on
                  >>>the C++ standards committee since 1997 and have written several
                  >>>related proposals, c.f. http://tinyurl.com/ovpe.[/color]
                  >>
                  >> OK - sorry for that.[/color]
                  >
                  >No prob.
                  >[color=green]
                  >> I remain surprised that this degree of specialisation occurs, but
                  >> it's a case of live and learn I suppose.[/color]
                  >
                  >Sorry, what specialization?[/color]

                  Presumably template specialisation - such that the special case of
                  std::pair<T,T> picks up the iterating functionality that
                  std::pair<T,U> lacks (begin, end etc). That is what I thought you were
                  saying.

                  Or am I still getting this wrong?


                  --
                  Steve Horne

                  steve at ninereeds dot fsnet dot co dot uk

                  Comment

                  • David Abrahams

                    #54
                    Re: Comment on PEP-0322: Reverse Iteration Methods

                    Stephen Horne <$$$$$$$$$$$$$$ $$$@$$$$$$$$$$$ $$$$$$$$$.co.uk > writes:
                    [color=blue][color=green]
                    >>Sorry, what specialization?[/color]
                    >
                    > Presumably template specialisation - such that the special case of
                    > std::pair<T,T> picks up the iterating functionality that
                    > std::pair<T,U> lacks (begin, end etc). That is what I thought you were
                    > saying.
                    >
                    > Or am I still getting this wrong?[/color]

                    Yeah, slightly. You don't need a begin() member function in order to
                    make an iterator. The interface might look like:

                    std::for_each(p air_iterator<T> (my_pair), pair_iterator<T >(), f);

                    Decoupling is the way to go, man! :^)

                    --
                    Dave Abrahams
                    Boost Consulting

                    Comment

                    • Stephen Horne

                      #55
                      Re: Comment on PEP-0322: Reverse Iteration Methods

                      On Sun, 28 Sep 2003 11:22:11 -0400, David Abrahams
                      <dave@boost-consulting.com> wrote:
                      [color=blue]
                      >Stephen Horne <$$$$$$$$$$$$$$ $$$@$$$$$$$$$$$ $$$$$$$$$.co.uk > writes:
                      >[color=green][color=darkred]
                      >>>Sorry, what specialization?[/color]
                      >>
                      >> Presumably template specialisation - such that the special case of
                      >> std::pair<T,T> picks up the iterating functionality that
                      >> std::pair<T,U> lacks (begin, end etc). That is what I thought you were
                      >> saying.
                      >>
                      >> Or am I still getting this wrong?[/color]
                      >
                      >Yeah, slightly. You don't need a begin() member function in order to
                      >make an iterator. The interface might look like:
                      >
                      > std::for_each(p air_iterator<T> (my_pair), pair_iterator<T >(), f);
                      >
                      >Decoupling is the way to go, man! :^)[/color]

                      Ah - I get it! - std::pair doesn't exactly support iteration itself,
                      but a support class can be used to add that capability.

                      You can do this in any language. For instance, did you know that
                      Python classes supports iterating through the subset of their
                      attribute that have names beginning with "a", interleaved with
                      insults? Yes, all you need is to use this generator...

                      def A_Attrib_Gen (p_Instance) :
                      for i in dir (p_Instance) :
                      if i[0] = "a" :
                      yield i
                      yield "stupid stupid stupid"

                      Well, OK, maybe this is a little unfair - this generator isn't exactly
                      in the library, but with a little luck you see my point.

                      When you say "you can in fact iterate on std::pair<T,T> with the usual
                      C++ iterator protocol" it implies to me that std::pair<T,T> provides
                      the iterator protocol itself - not that some other class provides a
                      way to support iteration over the pair. After all, there is *always*
                      some way to support iteration of *anything*.

                      But maybe I'm just being overliteral.


                      --
                      Steve Horne

                      steve at ninereeds dot fsnet dot co dot uk

                      Comment

                      • David Abrahams

                        #56
                        Re: Comment on PEP-0322: Reverse Iteration Methods

                        Stephen Horne <$$$$$$$$$$$$$$ $$$@$$$$$$$$$$$ $$$$$$$$$.co.uk > writes:
                        [color=blue]
                        > On Sun, 28 Sep 2003 11:22:11 -0400, David Abrahams
                        > <dave@boost-consulting.com> wrote:
                        >[color=green]
                        >>Stephen Horne <$$$$$$$$$$$$$$ $$$@$$$$$$$$$$$ $$$$$$$$$.co.uk > writes:
                        >>[color=darkred]
                        >>>>Sorry, what specialization?
                        >>>
                        >>> Presumably template specialisation - such that the special case of
                        >>> std::pair<T,T> picks up the iterating functionality that
                        >>> std::pair<T,U> lacks (begin, end etc). That is what I thought you were
                        >>> saying.
                        >>>
                        >>> Or am I still getting this wrong?[/color]
                        >>
                        >>Yeah, slightly. You don't need a begin() member function in order to
                        >>make an iterator. The interface might look like:
                        >>
                        >> std::for_each(p air_iterator<T> (my_pair), pair_iterator<T >(), f);
                        >>
                        >>Decoupling is the way to go, man! :^)[/color]
                        >
                        > Ah - I get it! - std::pair doesn't exactly support iteration itself,
                        > but a support class can be used to add that capability.
                        >
                        > You can do this in any language.[/color]

                        Yes; I never implied otherwise.
                        [color=blue]
                        > For instance, did you know that Python classes supports iterating
                        > through the subset of their attribute that have names beginning with
                        > "a", interleaved with insults?[/color]

                        I never, anywhere, said "std::pair supports..."
                        [color=blue]
                        > Yes, all you need is to use this
                        > generator...
                        >
                        > def A_Attrib_Gen (p_Instance) :
                        > for i in dir (p_Instance) :
                        > if i[0] = "a" :
                        > yield i
                        > yield "stupid stupid stupid"
                        >
                        > Well, OK, maybe this is a little unfair - this generator isn't exactly
                        > in the library, but with a little luck you see my point.[/color]

                        Your sarcasm is briefly amusing, but unwarranted.
                        [color=blue]
                        > When you say "you can in fact iterate on std::pair<T,T> with the usual
                        > C++ iterator protocol" it implies to me that std::pair<T,T> provides
                        > the iterator protocol itself[/color]

                        Hey, it's not my fault you read what you want to see into what I
                        posted.
                        [color=blue]
                        > - not that some other class provides a
                        > way to support iteration over the pair. After all, there is *always*
                        > some way to support iteration of *anything*.
                        >
                        > But maybe I'm just being overliteral.[/color]

                        No, you just don't know what "the usual iterator protocol" means. It
                        has to do with the protocol for using iterators, and begin()/end() are
                        nowhere in the iterator requirements. They're part of the container
                        requirements. There are many iterators that have nothing to do with
                        containers and have never been passed through a begin()/end().
                        Pointers to built-in arrays are one obvious example.

                        This whole discussion started out talking about what the Python
                        protocol for manipulating iterators should be. The fact that
                        iterators must themselves have an __iter__ method in Python may just
                        be making this more confusing than it needs to be.

                        --
                        Dave Abrahams
                        Boost Consulting

                        Comment

                        • Stephen Horne

                          #57
                          Re: Comment on PEP-0322: Reverse Iteration Methods


                          It was my intention to explain the origins of my misunderstandin g,
                          though certainly in a slightly less than serious way and with a big
                          dollop of its-not-all-my-fault-you-know. I tend to screw this kind of
                          thing up, and it seems I have done so again here.

                          Everything you have said in your last reply was at least 95% valid,
                          but there is a point I'd still like to make...
                          [color=blue]
                          >I never, anywhere, said "std::pair supports..."[/color]
                          ....[color=blue][color=green]
                          >> When you say "you can in fact iterate on std::pair<T,T> with the usual
                          >> C++ iterator protocol" it implies to me that std::pair<T,T> provides
                          >> the iterator protocol itself[/color]
                          >
                          >Hey, it's not my fault you read what you want to see into what I
                          >posted.[/color]
                          ....[color=blue][color=green]
                          >> But maybe I'm just being overliteral.[/color]
                          >
                          >No, you just don't know what "the usual iterator protocol" means.[/color]

                          I never said, anywhere, that you said that "std::pair supports..." if
                          we are being that pedantic, but in the life of this thread neither of
                          us really has been that pedantic. I quoted your exact words for the
                          crucial point, which were...

                          "you can in fact iterate on std::pair<T,T> with the usual C++ iterator
                          protocol"

                          Pedantically speaking, this is imprecise language. Most significantly,
                          there is no such thing as "the usual C++ iterator protocol". An
                          iterator may implement any one of five different iterator protocols,
                          and these protocols have surprisingly little in common. All require an
                          operator++ and all require a dereference-style operator* and that is
                          it.

                          Actually, even the operator* isn't as common as it seems - input
                          iterators only support read access, output ones only write access - so
                          the practical commonality is limited to the operator++.

                          But then you weren't writing a standards document, and I wasn't
                          reading it as a standards document.

                          To most C++ programmers most of the time, the words "the usual C++
                          iterator protocol" don't have the pedantic meaning set by the C++
                          standard - they are not just about having an operator++. They have a
                          somewhat more pragmatic meaning, which includes the usual means of
                          obtaining iterators from containers. std::pair *is* a container in the
                          general sense of containing other objects, even though in the C++
                          standards document context it is not formally considered a container.

                          Of course there is room for misinterpretati on in virtually any piece
                          of writing - criticism of your choice of words was certainly
                          intentional, but meant to be lighthearted.

                          But if you really believe that I "read what [I] want to see into what
                          [you] posted" then I'm afraid you're wrong. I saw an implication which
                          you never intended, but that was right at the start when I had no
                          reason to "want to see" anything in particular.

                          I do have a certain history in this kind of
                          minor-misunderstandin g-gets-overblown storyline, as Alex Martelli I
                          think can confirm if he's still following the thread. Actually, he'll
                          probably say you should consider yourself lucky that it only got this
                          bad ;-)

                          Anyway, I'm in no doubt that I'm primarily (probably entirely)
                          responsible for the 'overblown' part especially with my previous post.
                          I appologise for that.

                          [color=blue]
                          >This whole discussion started out talking about what the Python
                          >protocol for manipulating iterators should be. The fact that
                          >iterators must themselves have an __iter__ method in Python may just
                          >be making this more confusing than it needs to be.[/color]

                          We may think of '__iter__' as part of the iterator protocol but,
                          pedantically speaking, it is no more part of the Python iterator
                          protocol than 'begin' is part of the C++ iterator protocol.

                          Iterators don't have to have an '__iter__' method in Python. Iterators
                          only have to have a 'next' method. It is the iterable object that
                          implements '__iter__'. And, as with getting C++ iterators from 'begin'
                          etc, even that is a convention rather than a requirement.

                          Sometimes iterators do have an '__iter__' method, but that normally
                          just returns self - it's a quick-fix convenience for when iterators
                          end up in a context where an iterable object is expected.

                          I guess our mindsets aren't so different that we can't make similar
                          mistakes ;-)


                          BTW - there's no reason why an iterator can't have additional methods
                          beyond those required for the iterator protocol. So a container class
                          could, for instance, support the following...

                          for i in iter (container).ran ge (begin, end).reverse () :
                          ...

                          Simply by defining its iterator class as something like...

                          class Iter (object) :
                          def __init__ (self, p_Src) :
                          "Keep ref to container to iterate, plus other setup stuff."
                          self.Src = p_Src
                          ...

                          def __iter__ (self) :
                          "Allow iterator to behave as iterable for convenience"
                          return self

                          def range (self, p_Begin, p_End) :
                          "Set restriction on range to be iterated"
                          ...
                          return self

                          def reverse (self) :
                          "Set reverse-order iteration mode"
                          ...
                          return self

                          def next (self) :
                          "Get next item"
                          ...

                          Which reminds me of Paul Foleys post in "Thoughts on PEP284",
                          Message-ID: <m2eky8dtny.fsf @mycroft.actrix .gen.nz>, about Lisp-like
                          for-loops - though actually it's really just a minor variation of what
                          Raymond suggested right from the start.

                          Hmmm - possibly this suggestion should be made closer to the root.


                          --
                          Steve Horne

                          steve at ninereeds dot fsnet dot co dot uk

                          Comment

                          • Stephen Horne

                            #58
                            Re: Comment on PEP-0322: Reverse Iteration Methods

                            On Thu, 25 Sep 2003 00:58:45 GMT, "Raymond Hettinger"
                            <vze4rx4y@veriz on.net> wrote:
                            [color=blue]
                            >Please comment on the new PEP for reverse iteration methods.
                            >Basically, the idea looks like this:[/color]

                            I have one last suggestion to make on this. Instead of adding a method
                            to the container, possibly it should be added to the iterator.

                            If the iterator class was roughly equivalent to the following...

                            class Iter (object) :
                            def __init__ (self, p_Src) :
                            "Keep ref to container to iterate, plus other setup stuff."
                            self.Src = p_Src
                            ...

                            def __iter__ (self) :
                            "Allow iterator to behave as iterable for convenience"
                            return self

                            def reverse (self) :
                            "Set reverse-order iteration mode"
                            ...
                            return self

                            def next (self) :
                            "Get next item"
                            ...

                            We could write...

                            for i in iter (seq).reverse () :

                            Possible advantages being...

                            1. The need for/existence of an iterator is made explicit by the
                            already familiar 'iter' call.

                            2. Because the 'reverse' method is applied to the iterator rather
                            than the container, the existing spelling can be used without
                            worries about iterating over strings (or user classes) that
                            already have a 'reverse' method.

                            3. It's an extensible approach (other 'iterator modifiers' could be
                            defined in much the same way, e.g. range restriction) yet at the
                            same time both simple and lightweight.

                            The xrange and enumerate classes would probably also adopt the
                            'reverse' spelling for consistency...

                            for i in xrange(10).reve rse() :
                            ...


                            --
                            Steve Horne

                            steve at ninereeds dot fsnet dot co dot uk

                            Comment

                            • David Abrahams

                              #59
                              Re: Comment on PEP-0322: Reverse Iteration Methods


                              I wasn't even going to post this to the list, because it's so full of
                              static and other unpythonic stuff. But then, Stephen hides his email
                              address, and there is one real Python-related issue at the bottom,
                              so...

                              Stephen Horne <$$$$$$$$$$$$$$ $$$@$$$$$$$$$$$ $$$$$$$$$.co.uk > writes:
                              [color=blue]
                              > It was my intention to explain the origins of my misunderstandin g,
                              > though certainly in a slightly less than serious way and with a big
                              > dollop of its-not-all-my-fault-you-know.[/color]

                              I didn't need to have an assignment of blame in order to find closure
                              with this thread. I was just trying to be helpful.
                              [color=blue]
                              > I tend to screw this kind of thing up, and it seems I have done so
                              > again here.[/color]

                              Then I can't understand why you continue to charge about in the china
                              shop....
                              [color=blue]
                              > I never said, anywhere, that you said that "std::pair supports..." if
                              > we are being that pedantic, but in the life of this thread neither of
                              > us really has been that pedantic.[/color]

                              Seems like you've started.
                              [color=blue]
                              > I quoted your exact words for the crucial point, which were...
                              >
                              > "you can in fact iterate on std::pair<T,T> with the usual C++ iterator
                              > protocol"
                              >
                              > Pedantically speaking, this is imprecise language.[/color]

                              No, there is a common subset of all iterator requirements and that's
                              what I was referring to.
                              [color=blue]
                              > Most significantly, there is no such thing as "the usual C++
                              > iterator protocol". An iterator may implement any one of five
                              > different iterator protocols, and these protocols have surprisingly
                              > little in common. All require an operator++ and all require a
                              > dereference-style operator* and that is it.[/color]

                              And that is the usual iterator protocol. I happen to know exactly
                              what those protocols have in common.
                              [color=blue]
                              > Actually, even the operator* isn't as common as it seems - input
                              > iterators only support read access, output ones only write access[/color]

                              Actually it's subtler than that. You can have input/output iterators
                              which support random access which aren't random access iterators
                              because they don't support lvalue access. So what, though?
                              [color=blue]
                              > - so the practical commonality is limited to the operator++.[/color]

                              You need operator* regardless.
                              [color=blue]
                              > But then you weren't writing a standards document, and I wasn't
                              > reading it as a standards document.[/color]

                              That's why I didn't understand why you were giving me such a hard
                              time. Because it's informal speech I'm supposed to do quadruple duty
                              to make sure you haven't misinterpreted me? I really was going out
                              of my way to explain this stuff to you politely.
                              [color=blue]
                              > To most C++ programmers most of the time, the words "the usual C++
                              > iterator protocol" don't have the pedantic meaning set by the C++
                              > standard - they are not just about having an operator++[/color]

                              And operator*.
                              [color=blue]
                              > They have a somewhat more pragmatic meaning, which includes the
                              > usual means of obtaining iterators from containers. std::pair *is* a
                              > container in the general sense of containing other objects, even
                              > though in the C++ standards document context it is not formally
                              > considered a container.[/color]

                              Then so is

                              struct { int x, y; };

                              Also, so is char[4], and unsigned long is a container of at least 32
                              bits.

                              This is getting ridiculous. It seems like you want to have a pedantic
                              debate about terms whose meaning is going to be defined by your
                              completely informal and subjective interpretation.
                              [color=blue]
                              > Of course there is room for misinterpretati on in virtually any piece
                              > of writing - criticism of your choice of words was certainly
                              > intentional, but meant to be lighthearted.
                              >
                              > But if you really believe that I "read what [I] want to see into what
                              > [you] posted" then I'm afraid you're wrong. I saw an implication which
                              > you never intended, but that was right at the start when I had no
                              > reason to "want to see" anything in particular.
                              >
                              > I do have a certain history in this kind of
                              > minor-misunderstandin g-gets-overblown storyline, as Alex Martelli I
                              > think can confirm if he's still following the thread. Actually,
                              > he'll probably say you should consider yourself lucky that it only
                              > got this bad ;-)
                              >
                              > Anyway, I'm in no doubt that I'm primarily (probably entirely)
                              > responsible for the 'overblown' part especially with my previous post.
                              > I appologise for that.[/color]

                              Thanks, I think. This is somewhat of a backhanded apology, but I'll
                              take it. [If you had just stopped with the last message, I wouldn't
                              even feel it mattered].
                              [color=blue][color=green]
                              >>This whole discussion started out talking about what the Python
                              >>protocol for manipulating iterators should be. The fact that
                              >>iterators must themselves have an __iter__ method in Python may just
                              >>be making this more confusing than it needs to be.[/color]
                              >
                              > We may think of '__iter__' as part of the iterator protocol but,
                              > pedantically speaking, it is no more part of the Python iterator
                              > protocol than 'begin' is part of the C++ iterator protocol.
                              >
                              > Iterators don't have to have an '__iter__' method in Python. Iterators
                              > only have to have a 'next' method. It is the iterable object that
                              > implements '__iter__'. And, as with getting C++ iterators from 'begin'
                              > etc, even that is a convention rather than a requirement.[/color]

                              Sorry,



                              Read it twice, carefully.
                              [color=blue]
                              > Sometimes iterators do have an '__iter__' method, but that normally
                              > just returns self[/color]

                              Always.
                              [color=blue]
                              > - it's a quick-fix convenience for when iterators
                              > end up in a context where an iterable object is expected.
                              >
                              > I guess our mindsets aren't so different that we can't make similar
                              > mistakes ;-)[/color]

                              I'm afraid not. I never, ever make mistakes in the first place ;->

                              infallib-ly y'rs
                              --
                              Dave Abrahams
                              Boost Consulting

                              Comment

                              • Stephen Horne

                                #60
                                Re: Comment on PEP-0322: Reverse Iteration Methods

                                On Mon, 29 Sep 2003 08:15:41 -0400, David Abrahams
                                <dave@boost-consulting.com> wrote:
                                [color=blue]
                                >That's why I didn't understand why you were giving me such a hard
                                >time. Because it's informal speech I'm supposed to do quadruple duty
                                >to make sure you haven't misinterpreted me? I really was going out
                                >of my way to explain this stuff to you politely.[/color]

                                Nope - occasional misreadings are a fact of life and shouldn't be a
                                big deal. But when you said "I never, anywhere, said "std::pair
                                supports..."" that seemed very pedantic to me, as the issue wasn't
                                your precise words but the meaning behind them. And when you said
                                "Hey, it's not my fault you read what you want to see into what I
                                posted." you seemed to be claiming that there was no room for
                                reasonable misinterpretati on in your original words and that I was
                                100% to blame for the misinterpretati on.

                                The whole point of my pedanticism was to point out that your original
                                statement was informal and subjective and that, while that was
                                certainly wholy appropriate, there was room for accidental
                                misinterpretati on. IIRC I was not even the first to misinterpret - I
                                simply replied to Alex Martelli who had already misinterpreted your
                                words the same way that I did. So being made a scapegoat seemed
                                unfair.

                                And now I seem to be whining about it far to much, but really I just
                                want this point to be understood - and I wish I had been clear about
                                it in my last post.
                                [color=blue]
                                >Then so is
                                >
                                > struct { int x, y; };
                                >
                                >Also, so is char[4], and unsigned long is a container of at least 32
                                >bits.[/color]

                                Not in the pedantic 'C++ standard definition' sense of course, but the
                                C++ standard has taken an existing word and tied a more restrictive
                                meaning to it. In the wider world the original unrestricted meaning is
                                still valid.

                                To me both structs and char arrays are containers in the
                                less-restrictive sense. After all, if a C programmer talks about
                                containers what is he referring to? And in C# even a fixed-size array
                                is implemented using a library class.

                                An unsigned long, no - that is a single atomic item. But then again,
                                IIRC, in the pre-C++ days when I first learned programming, 'container
                                for a value' was one common way of explaining the concept of a
                                variable ;-)
                                [color=blue]
                                >Thanks, I think. This is somewhat of a backhanded apology, but I'll
                                >take it. [If you had just stopped with the last message, I wouldn't
                                >even feel it mattered].[/color]

                                I felt it mattered because I felt that I was being held soley and
                                entirely responsible for a mistake that I felt wasn't unreasonable.

                                I appologise for the misinterpretati on because I did misinterpret, and
                                I particularly appologise for the overblowing because it arises out of
                                my oversensitivity to certain things you said - which I certainly have
                                no right to given the sarcastic tone of my earlier post, and in any
                                case I have no doubt your words resulted from frustration.

                                I do not, however, accept that I am enirely and soley to responsible
                                for the misinterpretati on.

                                My persistence in sticking to this may seem bizarre and petty, but
                                there are reasons for my being bizarre and petty over such things.
                                Lets just call it 'desperate defending of what little self esteem I
                                have left' - and yes, it does tend to be counterproducti ve :-(
                                [color=blue]
                                >http://www.python.org/doc/current/li...r.html#l2h-149
                                >
                                >Read it twice, carefully.[/color]

                                OK - you are right and I am feeling a right fool. Sorry.
                                [color=blue]
                                >I'm afraid not. I never, ever make mistakes in the first place ;->
                                >
                                >infallib-ly y'rs[/color]

                                :-)


                                --
                                Steve Horne

                                steve at ninereeds dot fsnet dot co dot uk

                                Comment

                                Working...