Version 1.1 of ai12s/ai12-0188-1.txt

Unformatted version of ai12s/ai12-0188-1.txt version 1.1
Other versions for file ai12s/ai12-0188-1.txt

!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.]


Questions? Ask the ACAA Technical Agent