comp.lang.ada
 help / color / mirror / Atom feed
From: Brad Moore <bmoore.ada@gmail.com>
Subject: Re: Two approaches of iterators for the key-value pairs
Date: Fri, 27 Nov 2015 15:11:44 -0800 (PST)
Date: 2015-11-27T15:11:44-08:00	[thread overview]
Message-ID: <f822f37e-a1ab-4c6e-9e5f-0eb5e286e528@googlegroups.com> (raw)
In-Reply-To: <834c6afa-870e-4921-a1f1-4fe2b061811a@googlegroups.com>

On Friday, November 27, 2015 at 12:38:27 PM UTC-7, ytomino wrote:
> 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 out, should probably be called "Rosen Technique". However that has nothing to 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));
> 

OK, I see what you mean now.
If we were to go forward with this proposal, I think the type should probably 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 written into AI.
> 
> https://github.com/ytomino/drake/blob/master/source/environment/a-envvar.ads
> https://github.com/ytomino/drake/blob/master/source/environment/machine-apple-darwin/s-naenva.ads
> 
> 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.
> 
> 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:
> > > 
> > > 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;
> > > 
> > > On the other hand, as we already know, a loop for Ada.Containers.Hashed_Maps/Ordered_Maps:
> > > 
> > > for I *in* The_Map_Object.Iterate loop
> > >    -- I is Cursor
> > >    Key (E) -- key
> > >    Element (E), Reference (E).Element.all -- value
> > > end loop;
> > 
> > All the existing containers are iterable containers, so they support
> > both using "of" and "in" syntax for loops. Using "of" is generally preferable
> > because cursors are implicit, and the code written by the user is therefore simpler. Using "in" syntax can also be used by obtaining an Iterator object, but this gives you a cursor instead of a container element, so you typically would need to write some extra calls to get to the container element from the cursor object.
> > 
> > 
> > This code excerpt you had above would not compile, so it is probably confusing 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 see,
> > the "of" format is simpler, and hopefully easier to read and understand.
> > 
> > with Ada.Containers.Hashed_Maps; use Ada;
> > procedure Test_Iterator is
> >    
> >    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));
> >    
> >    package Maps is new Ada.Containers.Hashed_Maps 
> >      (Key_Type        => Student_Id,
> >       Element_Type    => Grade,
> >       Hash            => Hash,
> >       Equivalent_Keys => "=");
> > 
> >    School : Maps.Map;
> >    
> > begin
> > 
> >    School.Insert (Key      => 123456,    -- Student A
> >                   New_Item => 90);
> >    School.Insert (Key      => 789123,    -- Student B
> >                   New_Item => 65);
> > 
> >    -- Iterate using "in" syntax (for an iterator)
> >    for Cursor in School.Iterate loop
> >       School.Replace (Key => Maps.Key (Cursor), 
> >                       New_Item => Maps.Element (Cursor) + 1);
> >    end loop;
> > 
> >    -- Iterate using "of" syntax (for an iterable containter)
> >    for Grade of School loop
> >       Grade := Grade + 1;
> >    end loop;
> > 
> >    
> > 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) := School (Cursor) + 1;
>    end loop;

Good point..., a better way to write this using an Iterator.
> 
> > 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 the end, or may even not make the cut for Ada 202x.
> > 
> > Essentially, the design choice discussed in the AI is whether to expose an 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‐taught. 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 its good to hear the feedback.

>  
> > 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.)

Not sure what you mean here. Hashed_Maps/Ordered_Maps also already uses "of", 
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 somewhere in the loop.

> 
> > 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 case, as with other existing standard container types and as seen in my example 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.Directories and/or Ada.Environment_Variables, should the design be to 
> > expose just an Iterator type, or both an Iterator Type, and an Iterable container type?
> > 
> > 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 either way.
> 
> If I were to venture my opinion, the former is better to write a generic subprogram:
> 
>   generic
>      type Cursor is private;
>      with package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor);
>      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 their own, are there cases where creating an Iterator type makes better sense than creating an Iterable container type?  The ACATS test involving the Prime 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.
> > 
> > In other words, can general guidance be given about how to choose an approach, or does it not really matter, and the writer of such abstractions should choose which ever approach they fancy? 
> 
> 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, then 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 type so that Iterable container syntax can be used.

Brad

> 
>   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 (Output_Cursor);
>      Output_Iterator : Output_Iterator_Interfaces.Forward_Iterator'Class := ...;
>      ...
> 
> But, I can't get a sense of satisfaction.
> 
> Thanks.

  parent reply	other threads:[~2015-11-27 23:11 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-27 15:25 Two approaches of iterators for the key-value pairs ytomino
2015-11-27 16:30 ` Dmitry A. Kazakov
2015-11-27 18:08   ` ytomino
2015-11-27 20:50     ` Dmitry A. Kazakov
2015-11-27 22:52     ` bj.mooremr
2015-11-27 17:00 ` Pascal Obry
2015-11-27 18:25   ` ytomino
2015-11-27 17:43 ` Brad Moore
2015-11-27 19:38   ` ytomino
2015-11-27 19:46     ` ytomino
2015-11-27 23:11     ` Brad Moore [this message]
2015-11-28  8:58       ` Simon Wright
2015-11-28 19:54         ` Brad Moore
2015-11-28 23:34           ` Simon Wright
2015-11-29 21:17             ` Bob Duff
2015-11-29 16:17         ` Simon Wright
2015-11-29 17:55       ` ytomino
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox