From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: A few questions Date: Thu, 19 Nov 2015 09:52:52 +0100 Organization: cbb software GmbH Message-ID: <1wew1bio4hygc.xotxd22aq47g.dlg@40tude.net> References: <5007b311-5d2e-448c-b8c8-fc2e2d88ea5e@googlegroups.com> <8hw612c7lfik.1cy0uanjjnpzv$.dlg@40tude.net> Reply-To: mailbox@dmitry-kazakov.de NNTP-Posting-Host: TWQ9mg4k1m/sph/eQ+zHLA.user.speranza.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: 40tude_Dialog/2.0.15.1 X-Notice: Filtered by postfilter v. 0.8.2 Xref: news.eternal-september.org comp.lang.ada:28453 Date: 2015-11-19T09:52:52+01:00 List-Id: On Wed, 18 Nov 2015 16:27:31 -0600, Randy Brukardt wrote: > "Dmitry A. Kazakov" wrote in message > news:ojkj222dh308.y5p6iz7kqgjc.dlg@40tude.net... >> On Tue, 17 Nov 2015 15:30:28 -0600, Randy Brukardt wrote: >> >>> "Dmitry A. Kazakov" wrote in message >>> news:8hw612c7lfik.1cy0uanjjnpzv$.dlg@40tude.net... >>>> On Mon, 16 Nov 2015 13:13:05 -0600, Randy Brukardt wrote: >>>> >>>>> You're speaking nonsense. The element is part of the container, and the >>>>> only way to access it is from the container. >>>> >>>> I think you are confusing indices with iterators. The very concept of the >>>> iterator is accessing elements without the container as opposed to the >>>> index. >>> >>> That's surely not my idea of an iterator. And it doesn't work for Ada in any >>> case, as that would allow altering elements of constant containers (we >>> prevent that in the containers library by requiring an "in out" container >>> parameter in all cases where modifications are allowed). >> >> Access /= Update. Compare it with "access constant T" > > True, but irrelevant. Iterators without update compatibilities are way to > limiting to be of any value. I was answering your point. Clearly iterators, as pointers are, can be immutable themselves and/or refer to the immutable target. If container is immutable you should not be able to obtain a mutable-target iterator from it. Where is a problem? >> The difference between index and iterator is that accessing through the >> index requires the container. An index is always relative to some >> container. The iterator does not need the container, the container is >> implicit. > > This is the confusion between "iterators" and "cursors" that the C++ > libraries have. What you are describing as an "iterator" is exactly the > definition of a cursor in Ada. To me, iterators are active objects, not just > indexes. Iterator is not an index, I explained the difference. Index needs explicit container in the indexing operation. Iterator/cursor is nothing but a fat pointer. Pointers do not need explicit container (=memory pool) for dereferencing. This has nothing to do with specifically C++. E.g. DB interfaces have "cursors", GUI frameworks have "iterators" etc. The semantics of such object is same: Cursor = Iterator = Pointer >>>> Both concepts of >>>> iterator and index have fundamental operations to create a new instance >>>> referencing some other element (next, previous, sibling, parent, >>>> neighbour etc) >>> >>> The C++ containers mix up the ideas of iterators and cursors (they're >>> essentially the same thing there). By your description, you want them to >>> be the same -- but in that case, just use the cursors and be done with it. >>> You will sacrifice safety and ease-of-use to do so, but whatever. >> >> That is not my point. It is that Index + 1 is another index and that >> Iterator.Next is another iterator. From the interface point of view you >> don't need the container to get another instance of either. > > Next(Cursor) gets you another Cursor. (You can't use the prefix notation > because Cursors aren't tagged, and that's because we can't have primitive > operations of two tagged types, else they would have been tagged. But > otherwise this is identical.) You don't need the container to call Next. But > you do need the container to update the element. Both are just design bugs resulted due to language deficiencies. Clearly, there is no reason why postfix notation should not be allowed for the iterator objects, why the iterator type cannot be inherited from, why container is needed to update its element. As I said many times, fix the language type system first, then design standard containers. In that order. >> And regarding safety, it is very important that you don't need the >> container when accessing elements or advancing the iterator. Well-designed >> iterators meant to keep the iteration state *inside* the iterator object >> rather than in the container, for evident reasons. > > ??? > > If the container (not counting the contents of the elements) is modified > while the iterator is executing, it doesn't matter where the iteration is > happening -- you're not going to be able to maintain the invariants of the > execution. This is an aliasing problem, not a problem of iterator objects, though all iterators always have aliasing issues because of their referential semantics. BTW, speaking of inventing definitions, "iterator" is an object. It is not a process, the latter is called "iteration", "traversing", "search", "walkthrough", "enumeration" etc. > That happens with explicit iteration in the Ada.Containers (that is, > directly using Next and Cursors) -- where the effect is for the user to > figure out (and it's often erroneous) -- and that happens with any possible > iterator mechanism (using call-backs, or interfaces, or whatever) -- where > Ada uses a tampering check to avoid problems (the container does not allow > element insertions or deletions while an iteration is running). Yes, this is one of the worst form of enumeration because it is recursive, hello FP. Should be avoided where possible. > If you think allowing erroneous execution is somehow safe, you're in the > wrong language forum. The point was that keeping the iteration state in the container is more erroneous that keeping it outside in the iterator object. E.g. some implementations store last found element, deploy caching and book-keeping things in the container. That far less safe than keeping that stuff outside the container, e.g. in the iterator object. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de