From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.5-pre1 Path: eternal-september.org!reader02.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED.Y8x8cryPiEsgQj/JqVMF9A.user.gioia.aioe.org!not-for-mail From: Blady Newsgroups: comp.lang.ada Subject: Re: Generalized Loop Iteration and User-Defined Indexing with more than two parameters. Date: Sat, 7 Nov 2020 18:46:25 +0100 Organization: Aioe.org NNTP Server Message-ID: References: <86361qwvht.fsf@stephe-leake.org> NNTP-Posting-Host: Y8x8cryPiEsgQj/JqVMF9A.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:68.0) Gecko/20100101 Thunderbird/68.12.1 X-Notice: Filtered by postfilter v. 0.9.2 Content-Language: en-US X-Mozilla-News-Host: news://nntp.aioe.org Xref: reader02.eternal-september.org comp.lang.ada:60561 List-Id: Le 07/11/2020 à 01:58, Randy Brukardt a écrit : > "Blady" wrote in message >> Le 03/11/2020 à 12:05, Stephen Leake a écrit : > ... >> Ada RM 5.5.1 "User-Defined Iterator Types" says: >> "The Constant_Indexing aspect (if any) of an iterable container type T >> shall denote exactly one function with the following properties: >> ... >> if there are more than two parameters, the additional parameters all have >> default expressions." >> So I defines: >> function Get (Self : UXString; Position : Cursor; Substitute : in >> Character := '&') return Character; >> and then: >> for I in S1.Iterate loop >> C := S1 (I, '@'); >> F := S1 (I) = 'h'; >> Put_Line (Character'pos (C)'img & F'img); >> end loop; >> for CC of S2 loop >> C := CC; >> Put_Line (Character'pos (C)'img); >> end loop; >> >> However, I have 3 questions about iteration: >> 1) When using Default_Iterator aspect, both Iterator_Element and >> Constant_Indexing have to be defined also. >> If I understand why Constant_Indexing at least has to be defined, what is >> the purpose of Iterator_Element? > > Iterator functions work on cursors. The "of" form works on elements. In > order to figure out what constant indexing function to use in the element > iterator, we need to know both the parameter and result types. (Remember > that there can be many overloaded indexing functions, you're not restricted > to a single function [just a single name].) Thanks for clarification, I get it now. IMHO this clearly reduces the possibilities of the "for ... of ... loop" form to only one driven by Iterator_Element aspect. We might imagine iterate on a container on more than one its attributes. Let's iterate for instance on a collection of cars (Car_Coll) with different brands (Brand) and colors (Color): CC1, CC2 : Car_Coll; ... for B : Brand of CC1 loop -- iterate on the car brands present inside CC1 ... for C : Color of CC2 loop -- iterate on the car colors present inside CC2 ... if Iterator_Element is set to Color for example then the following code is equivalent to the previous one: for C of CC2 loop -- iterate on the car colors present inside CC2 ... If Iterator_Element is not set then the type in the loop must be provided. The indexing function would be then chosen either by Iterator_Element (by default) or overridden by the type given in the loop. Do this would help someone? Probably not a lot but I would give more symmetry between two for loop forms. > >> 2) In Ada.Iterator_Interfaces, why Has_Element is a generic formal >> parameter instead of an abstract function of Forward_Iterator interface? >> As: >> function Has_Element >> (Object : Forward_Iterator; >> Position : Cursor) return Boolean is abstract; >> The current way requires that Cursor type has the container reference >> embedded and cannot be a simple index type. > > I suppose other designs could have been chosen. The generic one was the > original proposal; probably the person that designed it doesn't use > interfaces very much. (I think that was me. ;-). If I recall correctly, the > original interface design didn't work at all, and the generic was a fix. But > I don't remember any of the details anymore (could look them up, but would > need more motivation for that :-). Does a message on Ada Comments could help ;-)? >> 3) Couldn't be the additional parameters of the Constant_Indexing function >> without parameters defaults and a for ... of form as one of the >> followings? >> function Get (Self : UXString; Position : Cursor; Substitute : in >> Character) return Character; >> ... >> for CC of S2 ('@') loop >> C := CC; >> Put_Line (Character'pos (C)'img); >> end loop; >> or less preferable: >> for CC of S2 loop >> C := CC ('@'); >> Put_Line (Character'pos (C)'img); >> end loop; > > I suppose, but that sort of thing would substantially complicate the > mechanism, especially resolution. > > Personally, I think of the "of" form of iterators as a convinient shorthand > to be used only in limited circumstances. The cursor form ("in"), the more > traditional form, should be used when you have more complex needs. For > instance, for the above: > > for CC in S2.Iterator loop > C := S2(CC, '@'); > Put_Line (Character'pos (C)'img); > end loop; > > Trying to jam everything into the shorthand just complicates the > implementation and makes it a lot harder for the reader. This is connected to point 1): Do this would help someone? Probably not a lot but I would give more symmetry between two for loop forms. > Randy Thanks Randy for your answers, Pascal.