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=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.129.0.212 with SMTP id 203mr44686752ywa.19.1448653105688; Fri, 27 Nov 2015 11:38:25 -0800 (PST) X-Received: by 10.182.42.195 with SMTP id q3mr551456obl.3.1448653105655; Fri, 27 Nov 2015 11:38:25 -0800 (PST) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!usenet.blueworldhosting.com!feeder01.blueworldhosting.com!peer03.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!f78no3572385qge.1!news-out.google.com!l1ni168igd.0!nntp.google.com!mv3no5508037igc.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Fri, 27 Nov 2015 11:38:25 -0800 (PST) In-Reply-To: <073bed9a-32f2-4045-93ec-064322edf883@googlegroups.com> Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=153.181.129.1; posting-account=Mi71UQoAAACnFhXo1NVxPlurinchtkIj NNTP-Posting-Host: 153.181.129.1 References: <0c524381-442a-49cc-9d72-27a654320153@googlegroups.com> <073bed9a-32f2-4045-93ec-064322edf883@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <834c6afa-870e-4921-a1f1-4fe2b061811a@googlegroups.com> Subject: Re: Two approaches of iterators for the key-value pairs From: ytomino Injection-Date: Fri, 27 Nov 2015 19:38:25 +0000 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Received-Bytes: 9113 X-Received-Body-CRC: 1595882931 Xref: news.eternal-september.org comp.lang.ada:28571 Date: 2015-11-27T11:38:25-08:00 List-Id: Thank you, Brad. I'm glad your reply! > I'm not sure what is being referred to here as a "boolean trick". Perhaps= you are referring to the mention of "Rosen Trick", which as Randy points o= ut, should probably be called "Rosen Technique". However that has nothing t= o do with "Boolean". The Rosen technique is a coding technique that allows = one to treat a read only "in" parameter as a modifiable "in out" parameter. I called the below point as "boolean trick". type Entry_Presence is new Boolean; -- the "cursor" type function Has_Element (EP : Entry_Presence) return Boolean is (Boolean (EP)); It's interesting for me because I had tried to implement the iterator for A= da.Environment_Variables. Sorry a personal matter, and please excuse the difference from AI because I= wrote this code with my image before the specific content has not been wri= tten into AI. https://github.com/ytomino/drake/blob/master/source/environment/a-envvar.ad= s https://github.com/ytomino/drake/blob/master/source/environment/machine-app= le-darwin/s-naenva.ads I made Cursor as pointer in the environment-block(envp), and used address-a= rithmetic to scan it. So, "Cursor is new Boolean" is shocking for me. Thanks to teach "Rosen Trick". I has known this technique, but not known the name of the technique. > > A loop for Ada.Environment_Variables would be like below, according to = this AI: > >=20 > > for E *of* Ada.Environment_Variables.All_Variables loop > > -- E is Iterator_Element (Name_Value_Pair_Type) > > Name (E) -- key > > Value (E) -- value > > end loop; > >=20 > > On the other hand, as we already know, a loop for Ada.Containers.Hashed= _Maps/Ordered_Maps: > >=20 > > for I *in* The_Map_Object.Iterate loop > > -- I is Cursor > > Key (E) -- key > > Element (E), Reference (E).Element.all -- value > > end loop; >=20 > All the existing containers are iterable containers, so they support > both using "of" and "in" syntax for loops. Using "of" is generally prefer= able > because cursors are implicit, and the code written by the user is therefo= re simpler. Using "in" syntax can also be used by obtaining an Iterator obj= ect, but this gives you a cursor instead of a container element, so you typ= ically would need to write some extra calls to get to the container element= from the cursor object. >=20 >=20 > This code excerpt you had above would not compile, so it is probably conf= using people. > It think it would be better to perhaps show a full simple working example= , such as incrementing each element of the container; > Here I show both forms of loop using a Hashed_Map container. As you can s= ee, > the "of" format is simpler, and hopefully easier to read and understand. >=20 > with Ada.Containers.Hashed_Maps; use Ada; > procedure Test_Iterator is > =20 > type Student_Id is new Positive; > type Grade is new Natural range 0 .. 100; > function Hash (Student : Student_Id) return Containers.Hash_Type is > (Containers.Hash_Type (Student)); > =20 > package Maps is new Ada.Containers.Hashed_Maps=20 > (Key_Type =3D> Student_Id, > Element_Type =3D> Grade, > Hash =3D> Hash, > Equivalent_Keys =3D> "=3D"); >=20 > School : Maps.Map; > =20 > begin >=20 > School.Insert (Key =3D> 123456, -- Student A > New_Item =3D> 90); > School.Insert (Key =3D> 789123, -- Student B > New_Item =3D> 65); >=20 > -- Iterate using "in" syntax (for an iterator) > for Cursor in School.Iterate loop > School.Replace (Key =3D> Maps.Key (Cursor),=20 > New_Item =3D> Maps.Element (Cursor) + 1); > end loop; >=20 > -- Iterate using "of" syntax (for an iterable containter) > for Grade of School loop > Grade :=3D Grade + 1; > end loop; >=20 > =20 > end Test_Iterator; Thanks for writing the example. However, I feel it's unfair because Hashed_Maps has Variable_Indexing. -- Iterate using "in" syntax (for an iterator) for Cursor in School.Iterate loop School (Cursor) :=3D School (Cursor) + 1; end loop; > For the AI for Ada 202x on Ada.Directories and Ada.Environment_Variables, > this is a work in progress, so it may end up looking very different in th= e end, or may even not make the cut for Ada 202x. >=20 > Essentially, the design choice discussed in the AI is whether to expose a= n Iterable Container type, or just an Iterator type. Sorry, I didn't have the intention to interrupt the discussion of AI. I already has made some my iterators with self=E2=80=90taught. So I want to= know the preference of people. I don't want to affect your work... Of course, I'm looking forward to the c= omplete of this AI. =20 > Both choices could be made to have the same interface for the user, with = the only difference being whether "in" or "of" appears in the loop. Yes. (And, Hashed_Maps/Ordered_Maps already use "in". So I felt "in" is suitable= .) > If we expose an Iterable container though, that also gives the ability to= use "in" syntax since an Iterable container is associated with an Iterator= type, and that Iterator type could be used in the loop. However, in that c= ase, as with other existing standard container types and as seen in my exam= ple above, using the "in" form would be a bit more awkward to use, compared= to the "of" form, so I suspect most people would just use "of". Well... > So the question really is, if we add Ada 2012 Iterator support to Ada.Dir= ectories and/or Ada.Environment_Variables, should the design be to=20 > expose just an Iterator type, or both an Iterator Type, and an Iterable c= ontainer type? >=20 > My thought is that the latter might be better mostly because it would be = more consistent with the other standard container types, but I could go eit= her way. If I were to venture my opinion, the former is better to write a generic su= bprogram: generic type Cursor is private; with package Iterator_Interfaces is new Ada.Iterator_Interfaces (Curso= r); with function Key (P : Cursor) return String; with function Element (P : Cursor) return String; procedure My_Logic (...); This generic subprogram can be compatible with Hashed_Maps/Ordered_Maps and= Environment_Variables. Conversely, the latter is acceptable if Hashed_Maps/Ordered_Maps expose Key= _Element_Pair_Type. > A secondary question might be for anyone creating such abstractions of th= eir own, are there cases where creating an Iterator type makes better sense= than creating an Iterable container type? The ACATS test involving the Pr= ime number iterator could be an example of such an iterator type, but note = I could have written that also as an Iterable Container type instead. >=20 > In other words, can general guidance be given about how to choose an appr= oach, or does it not really matter, and the writer of such abstractions sho= uld choose which ever approach they fancy?=20 I want to know it, too. I sometime try to write the generic package like below: generic type Input_Cursor is private; with package Input_Iterator_Interfaces is new Ada.Iterator_Interfaces = (Input_Cursor); Input_Iterator : Input_Iterator_Interfaces.Forward_Iterator'Class; type Element_Type (<>) is limited private; with function Element (Position : Input_Cursor) return Element_Type; package My_Filter is type Output_Cursor is private; package Output_Iterator_Interfaces is new Ada.Iterator_Interfaces (Out= put_Cursor); Output_Iterator : Output_Iterator_Interfaces.Forward_Iterator'Class := =3D ...; ... But, I can't get a sense of satisfaction. Thanks.