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.182.142.68 with SMTP id ru4mr12460644obb.33.1448665904491; Fri, 27 Nov 2015 15:11:44 -0800 (PST) X-Received: by 10.182.73.167 with SMTP id m7mr553804obv.11.1448665904463; Fri, 27 Nov 2015 15:11:44 -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!news.glorb.com!mv3no5671173igc.0!news-out.google.com!l1ni189igd.0!nntp.google.com!mv3no4403801igc.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Fri, 27 Nov 2015 15:11:44 -0800 (PST) In-Reply-To: <834c6afa-870e-4921-a1f1-4fe2b061811a@googlegroups.com> Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=68.145.219.148; posting-account=lzqe5AoAAADHhp_gregSufVhvwu22fBS NNTP-Posting-Host: 68.145.219.148 References: <0c524381-442a-49cc-9d72-27a654320153@googlegroups.com> <073bed9a-32f2-4045-93ec-064322edf883@googlegroups.com> <834c6afa-870e-4921-a1f1-4fe2b061811a@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Re: Two approaches of iterators for the key-value pairs From: Brad Moore Injection-Date: Fri, 27 Nov 2015 23:11:44 +0000 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Xref: news.eternal-september.org comp.lang.ada:28576 Date: 2015-11-27T15:11:44-08:00 List-Id: On Friday, November 27, 2015 at 12:38:27 PM UTC-7, ytomino wrote: > Thank you, Brad. I'm glad your reply! >=20 > > I'm not sure what is being referred to here as a "boolean trick". Perha= ps you are referring to the mention of "Rosen Trick", which as Randy points= out, should probably be called "Rosen Technique". However that has nothing= to do with "Boolean". The Rosen technique is a coding technique that allow= s one to treat a read only "in" parameter as a modifiable "in out" paramete= r. >=20 > I called the below point as "boolean trick". >=20 > type Entry_Presence is new Boolean; -- the "cursor" type > function Has_Element > (EP : Entry_Presence) return Boolean is (Boolean (EP)); >=20 OK, I see what you mean now. If we were to go forward with this proposal, I think the type should probab= ly be called Cursor instead of Entry_Presence, (to be consistent with other= Container types), and it should be a private type. The fact that its just = a boolean type is an implementation detail, and of no concern to the user's= of the abstraction. > It's interesting for me because I had tried to implement the iterator for= Ada.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 w= ritten into AI. >=20 > https://github.com/ytomino/drake/blob/master/source/environment/a-envvar.= ads > https://github.com/ytomino/drake/blob/master/source/environment/machine-a= pple-darwin/s-naenva.ads >=20 > I made Cursor as pointer in the environment-block(envp), and used address= -arithmetic to scan it. > So, "Cursor is new Boolean" is shocking for me. >=20 > Thanks to teach "Rosen Trick". > I has known this technique, but not known the name of the technique. >=20 > > > A loop for Ada.Environment_Variables would be like below, according t= o 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.Hash= ed_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 pref= erable > > because cursors are implicit, and the code written by the user is there= fore simpler. Using "in" syntax can also be used by obtaining an Iterator o= bject, but this gives you a cursor instead of a container element, so you t= ypically would need to write some extra calls to get to the container eleme= nt from the cursor object. > >=20 > >=20 > > This code excerpt you had above would not compile, so it is probably co= nfusing people. > > It think it would be better to perhaps show a full simple working examp= le, such as incrementing each element of the container; > > Here I show both forms of loop using a Hashed_Map container. As you can= see, > > 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; >=20 > Thanks for writing the example. > However, I feel it's unfair because Hashed_Maps has Variable_Indexing. >=20 > -- Iterate using "in" syntax (for an iterator) > for Cursor in School.Iterate loop > School (Cursor) :=3D School (Cursor) + 1; > end loop; Good point..., a better way to write this using an Iterator. >=20 > > For the AI for Ada 202x on Ada.Directories and Ada.Environment_Variable= s, > > this is a work in progress, so it may end up looking very different in = the end, or may even not make the cut for Ada 202x. > >=20 > > Essentially, the design choice discussed in the AI is whether to expose= an Iterable Container type, or just an Iterator type. >=20 > 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= complete of this AI. Getting feedback on the preferences of people could influence the direction= that the AI takes, and ultimately we want to make the best decisions, so i= ts good to hear the feedback. > =20 > > Both choices could be made to have the same interface for the user, wit= h the only difference being whether "in" or "of" appears in the loop. >=20 > Yes. > (And, Hashed_Maps/Ordered_Maps already use "in". So I felt "in" is suitab= le.) Not sure what you mean here. Hashed_Maps/Ordered_Maps also already uses "of= ",=20 you can use either today, so how is one more suitable than the other? I think the "of" form involves less clutter that that user has to write, so= I would generally try to use that, unless you really need a Cursor somewhe= re in the loop. >=20 > > If we expose an Iterable container though, that also gives the ability = to use "in" syntax since an Iterable container is associated with an Iterat= or type, and that Iterator type could be used in the loop. However, in that= case, as with other existing standard container types and as seen in my ex= ample above, using the "in" form would be a bit more awkward to use, compar= ed to the "of" form, so I suspect most people would just use "of". >=20 > Well... >=20 > > So the question really is, if we add Ada 2012 Iterator support to Ada.D= irectories and/or Ada.Environment_Variables, should the design be to=20 > > expose just an Iterator type, or both an Iterator Type, and an Iterable= container type? > >=20 > > My thought is that the latter might be better mostly because it would b= e more consistent with the other standard container types, but I could go e= ither way. >=20 > If I were to venture my opinion, the former is better to write a generic = subprogram: >=20 > generic > type Cursor is private; > with package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cur= sor); > with function Key (P : Cursor) return String; > with function Element (P : Cursor) return String; > procedure My_Logic (...); >=20 > This generic subprogram can be compatible with Hashed_Maps/Ordered_Maps a= nd Environment_Variables. > Conversely, the latter is acceptable if Hashed_Maps/Ordered_Maps expose K= ey_Element_Pair_Type. >=20 > > A secondary question might be for anyone creating such abstractions of = their own, are there cases where creating an Iterator type makes better sen= se than creating an Iterable container type? The ACATS test involving the = Prime number iterator could be an example of such an iterator type, but not= e 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 ap= proach, or does it not really matter, and the writer of such abstractions s= hould choose which ever approach they fancy?=20 >=20 > I want to know it, too. > I sometime try to write the generic package like below: My sense is that if you dont need a container as part of the abstraction, t= hen perhaps it's better to just provide an Iterator type. All the existing = containers already were containers, so for those it made sense to make them= Iterable containers. Ada.Directories and Ada.Environment_Variables do not= currently have Containers associated with them, so perhaps an argument can= be made that they should be Iterators, rather than concoct a Container typ= e so that Iterable container syntax can be used. Brad >=20 > generic > type Input_Cursor is private; > with package Input_Iterator_Interfaces is new Ada.Iterator_Interface= s (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 (O= utput_Cursor); > Output_Iterator : Output_Iterator_Interfaces.Forward_Iterator'Class = :=3D ...; > ... >=20 > But, I can't get a sense of satisfaction. >=20 > Thanks.