Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Refer to the loop index in a *for .. of* loop #125

Open
clairedross opened this issue Nov 4, 2024 · 6 comments
Open

[feature] Refer to the loop index in a *for .. of* loop #125

clairedross opened this issue Nov 4, 2024 · 6 comments
Labels
enhancement New feature or request

Comments

@clairedross
Copy link
Contributor

Summary

A new attribute, possibly called Loop_Index, could be defined for the parameter of a for .. of loop to get the underlying index/cursor. Ideally, this would work both for loops over arrays, and loops using the Iterable aspect.

   procedure Do_Loop_1 (A : in out My_Array) is
   begin
      for E of A loop
         E := E + 1;
         pragma Loop_Invariant
           (for all K in A'First .. E'Loop_Index => A (I) = A'Loop_Entry (I) + 1);
      end loop;
   end Do_Loop_1;
   procedure Do_Loop_2 (S : in out My_Sequence) is
      C : Big_Natural := 0;
   begin
      for E of S loop
         if E = 0 then
           C := C + 1;
         end if;
         pragma Loop_Invariant (C <= E'Loop_Index);
      end loop;
   end Do_Loop_2;

Motivation

Currently, it is not possible to use for .. of loops in SPARK most of the time, as loop invariants generally need to refer to the underlying loop index/cursor etc. This is a shame as arguably for .. of loops are easier to read for programmers.

Caveats and alternatives

TBD

@clairedross clairedross added the enhancement New feature or request label Nov 4, 2024
@raph-amiard
Copy link
Member

I think this looks very reasonable. It's a bit frustrating to not be able to do a more elegant thing involving possibly tuples and unpacking, as it is done in many other languages.

I'm not sure it would be reasonable in Ada just because the involved effort is much larger, but I think it would be good to exhaust other ways (on paper of course), to justify that this is the best one for us.

@mosteo
Copy link

mosteo commented Nov 13, 2024

I seem to remember a syntactic sugar AI proposal in which you did

for (Key, Value) in Collection.Iterate loop

where Iterate is the already existing subprogram in e.g. standard Maps.

@clairedross
Copy link
Contributor Author

I seem to remember a syntactic sugar AI proposal in which you did

for (Key, Value) in Collection.Iterate loop
where Iterate is the already existing subprogram in e.g. standard Maps.

Yes, it is the kind of alternative @raph-amiard is referring to above I think. I suspect it might be more complicated to support due to the problem of typing the pair in particular. Basically, it would require adding a new syntax in Ada whereas the syntax proposed in the RFC has the advantage of only needing a new attribute. It is more common as an extension.

@sttaft
Copy link
Contributor

sttaft commented Nov 13, 2024

I seem to remember a syntactic sugar AI proposal in which you did

for (Key, Value) in Collection.Iterate loop

where Iterate is the already existing subprogram in e.g. standard Maps.

This syntax is consistent with the Ada 2022 syntax for Procedural Iterators, so would seem worth further investigation. See RM 5.5.3, with example:

for (Name, Val) of Ada.Environment_Variables.Iterate(<>) loop
   --  "(<>)" is optional because it is the last parameter
   Put_Line (Name & " => " & Val);
end loop;

@clairedross
Copy link
Contributor Author

Are procedural iterators already supported in GNAT? If so, I have no strong preference either ways.

@sttaft
Copy link
Contributor

sttaft commented Nov 20, 2024

Are procedural iterators already supported in GNAT? If so, I have no strong preference either ways.

I don't believe they have been implemented yet, but this might be the impetus they need.
-Tuck

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants