!standard 5.5.2(2/3) 16-06-02 AI12-0188-1/01 !class Amendment 16-06-02 !status work item 16-06-02 !status received 16-05-06 !priority Low !comment Microscopic isn't allowed here. - Editor. !difficulty Medium !subject Add container iterator form supporting iteration over keys !summary ** TBD. !problem Currently, the iterator form for iterating over containers only allows iteration over the elements of a container: for Elem of Container loop ... end loop; We have found many places where iterating over the keys of a map-like container is preferable. !proposal Add the following syntaxes: for (Key => Elem) of Container loop ... end loop; and for (Key => <>) of Container loop ... end loop; which provide, respectively, iteration over Key=>Elem pairs, and iteration over just keys. In both forms, the Key is a constant. In the first form, the Elem would be a variable if and only if the view of the Container is a variable. !wording ** TBD. !discussion Iterating using a cursor provides this capability without a complex new facility, but of course less conviniently. The facility proposed in AI12-0189-1 also can provide this capability (but new subprograms would need to be defined in the Map and Set containers). !ASIS !ACATS test An ACATS C-Test is needed to check that the new capabilities are supported. !appendix From: Tucker Taft Sent: Friday, May 6, 2016 9:08 AM Currently, the iterator form for iterating over containers only allows iteration over the elements of a container: for Elem of Container loop ... end loop; We have found many places where iterating over the keys of a map-like container is preferable. Hence, I would recommend we add the following syntaxes: for (Key => Elem) of Container loop ... end loop; and for (Key => <>) of Container loop ... end loop; which provide, respectively, iteration over Key=>Elem pairs, and iteration over just keys. In both forms, the Key is a constant. In the first form, the Elem would be a variable if and only if the view of the Container is a variable. I'll write up a full AI if this general idea makes sense to others. **************************************************************** From: Gary Dismukes Sent: Friday, May 6, 2016 1:19 PM The proposal sounds reasonable. I vote in favor of writing up an AI. **************************************************************** From: Jeff Cousins Sent: Friday, May 6, 2016 11:06 AM I hadn't thought about the syntax, but I had been intending to suggest iterating over the keys of maps, and I think John Barnes would like it too. So I would welcome an AI. **************************************************************** From: John Barnes Sent: Tuesday, May 10, 2016 4:50 AM Hear hear! **************************************************************** From: Randy Brukardt Sent: Tuesday, May 10, 2016 6:59 PM > Currently, the iterator form for iterating over containers only allows > iteration over the elements of a container: > > for Elem of Container loop > ... > end loop; This is certainly not true; the cursor form of iteration ought to be preferred in many circumstances (this being one of them). Indeed, the "of" form is a shorthand for various common cases; under no circumstances should it be considered the only way to do iteration. Secondly, it's possible to define an appropriate cursor iterator where the "cursors" are actually keys (that assumes that the keys are definite and nonlimited, as many will be). One "simply" instantiates the iterator generic appropriately: package Key_Iterators is new Ada.Iterator_Interfaces (Cursor => Key, Has_Element => Has_Element); and then defines an appropriate iterator type: type Key_Iterator is new Key_Iterators.Forward_Iterator with private; This does require defining appropriate First, Next, and Has_Element routines (and probably using the Rosen technique in Key_Iterator). But that's hardly more work than will be needed to use the below (assuming a new kind of interface is used). > We have found many places where iterating over the keys of a map-like > container is preferable. Hence, I would recommend we add the > following syntaxes: > > for (Key => Elem) of Container loop > ... > end loop; > > and > > for (Key => <>) of Container loop > ... > end loop; > > which provide, respectively, iteration over Key=>Elem pairs, and > iteration over just keys. > In both forms, the Key is a constant. In the first form, the Elem > would be a variable if and only if the view of the Container is a > variable. There'd be some value to this for indefinite keys (i.e. String), but... You'd have to have some additional operations somewhere to get the Key -- there aren't any of those currently in the iterator interfaces. And you're surely not allowed to get those out of thin air. Either you need new iterator interfaces, or new type aspects similar to Default_Iterator. Substantially more complicated than just some new syntax (and when is new syntax simple)? So, while the idea is sound, it barely even rises to the level of nice-to-have. We shouldn't be loading the next Ada up with nice-to-haves; we need other non-AdaCore vendors to catch up and we did plenty of nice-to-haves the last time around. (And this is the sort of thing that gives "committee-designed" languages a bad name -- everyone's pet projects get included.) > I'll write up a full AI if this general idea makes sense to others. Hopefully, only after you've handled the 10(!!!) other AIs that you have for homework. You, of all people, shouldn't be taking on more work without dealing with the huge pile you already have. (And you haven't even done the relatively easy homework, like read and comment on the AI draft I sent you back in November and that I've repeatedly reminded you of since.) **************************************************************** From: Tucker Taft Sent: Tuesday, May 10, 2016 8:51 PM >> Currently, the iterator form for iterating over containers only >> allows iteration over the elements of a container: >> >> for Elem of Container loop >> ... >> end loop; > > This is certainly not true; the cursor form of iteration ought to be > preferred in many circumstances (this being one of them). Indeed, the "of" > form is a shorthand for various common cases; under no circumstances > should it be considered the only way to do iteration. True, but these iterators are all about raising the level of abstraction, and cursors are too low level for many folks. We have found almost everyone using containers prefers the user-defined "of" iterators over those making explicit use of cursors. >> ... I'll write up a full AI if this general idea makes sense to others. > > Hopefully, only after you've handled the 10(!!!) other AIs that you > have for homework. ... Fair enough! **************************************************************** From: Florian Schanda Sent: Thursday, May 12, 2016 9:21 AM > We have found many places where iterating over the keys of a map-like > container is preferable. Hence, I would recommend we add the > following > syntaxes: > > for (Key => Elem) of Container loop > ... > end loop; > > and > > for (Key => <>) of Container loop > ... > end loop; A bit fat +1 from me. I think this one of the main things that I found irritating when using the containers ;) **************************************************************** From: Randy Brukardt Sent: Thursday, May 12, 2016 5:46 PM > So, while the idea is sound, it barely even rises to the level of > nice-to-have. We shouldn't be loading the next Ada up with > nice-to-haves; we need other non-AdaCore vendors to catch up and we > did plenty of nice-to-haves the last time around. (And this is the > sort of thing that gives "committee-designed" languages a bad name -- > everyone's pet projects get included.) I also note that this proposal is essentially redundant with the "lambda loop body" proposal (see the parallel thread [Editor's note: see AI12-0189-1]). The Map containers don't currently have the "right" iterator for that (only having a cursor version), but it would be easy enough to add that: procedure Iterate (Container : in Map; Process : not null access procedure (Key : in Key_Type; Element : in out Element_Type)); With this iterator subprogram in the Map containers, the "lambda loop body" proposal would give you what you want. I'm really dubious that a separate feature is warranted for this. **************************************************************** From: Tucker Taft Sent: Thursday, May 12, 2016 7:42 PM > ... I'm really dubious that a separate feature is warranted for this. I think you are in the minority on this one. But in any case it sounds like we should discuss the various alternatives in an ARG meeting before I spend time writing it up, given the amount of other homework still on my plate... **************************************************************** From: Randy Brukardt Sent: Thursday, May 12, 2016 8:09 PM > > ... I'm really dubious that a separate feature is warranted for this. > > I think you are in the minority on this one. The above is conditional on the "loop body procedures" getting defined. There is absolutely no justification for adding *two* more ways to write loops, with all of the implementation and definitional complexity that entails. And I'm much more sympathetic to the "loop body procedure" scheme given the mess that Brad went through to get the environment variable iterators to work. (Of course that was because of the aversion people have to "in out" parameters on functions...but too late to fix now.) Using "loop body procedures" rather than Brad's messy iterators seems like a win (there's complex wording either way, but the wording we'd do would be more general), and we'd get key iterators for almost free. We have to resist loading up Ada with every pet feature someone has (well, except mine of course ;-). Else there will be zero implementations of Ada 2020. > But in any case > it sounds like we should discuss the various alternatives in an ARG > meeting before I spend time writing it up, given the amount of other > homework still on my plate... Sounds like a plan. When are you getting back to me on my AI12-0064-2 draft? I'd like to finish it before I leave for the meeting (and not 3 minutes before the meeting ;-). **************************************************************** [Editor's note: This thread continues in AI12-0190-1, since it has much more to do with general lambdas than it does with this proposal.]