Date: Fri, 14 Feb 2025 09:38:06 +0000
On Fri, 14 Feb 2025 at 08:39, Jennifier Burnett via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> If (as has been the case whenever I've needed to this pattern before) what
> you actually need the loop to do is iterate over all valid indexes in
> reverse order, ranges has you covered already:
>
> for (std::size_t i : std::views::iota(0zu, vec.size()) |
> std::views::reverse)
>
Yup, alternatively:
for (auto&& [index, val] : views::enumerate(vec) | views::reverse)
> And if being able to define a range of integers with a custom step count
> is useful I'd suggest we'd want to instead add a third argument to iota
> before adding a new loop syntax to the core language. Although perhaps
> views::stride might already cover many of the cases you'd need a step
> count, unless you have an unsigned index that isn't a multiple of the step
> count and you're expecting overflow to cause the index go through the full
> range of the integer multiple times (although such cases would seem of
> unclear usefulness to me and seem more likely to be bugs)
>
>
> On 14 February 2025 07:16:20 GMT, Tiago Freire via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> The example is doubly bugged.
>> i>=0 is never false. And if size is 0 it size-1 overflows leading to max
>> value for the uint.
>>
>> The correct way would be.
>> for(std::size_t i = vec.size(); i-- > 0;)
>>
>> I guess the point being made is that with traditional loops, you can do
>> the wrong thing but the pattern looks good at first glance because it has
>> all the similar patterns of something that might be right when iterating
>> forwards. And it hopes to solve the same ambiguity with indexes as range
>> based for loops did with iterators.
>>
>> But again, this seems solvable without needing to add a new for loop
>> syntax.
>>
>> You could define something like:
>> for(size_t index: integer_interval(0, vec.size()))
>>
>> Or
>> for(size_t index: reverse_integer_interval(vec.size(), 0, 1))
>>
>> Where "interval" is not a list of all possible indexes, but 2 numbers
>> (start and 1 past last) that gives an iterator that counts numbers in that
>> interval.
>>
>> Would this solution work?
>>
>>
>>
>> ------------------------------
>> *From:* Std-Proposals <std-proposals-bounces_at_[hidden]> on behalf
>> of Sebastian Wittmeier via Std-Proposals <std-proposals_at_[hidden]>
>> *Sent:* Friday, February 14, 2025 7:41:25 AM
>> *To:* std-proposals_at_[hidden] <std-proposals_at_[hidden]>
>> *Cc:* Sebastian Wittmeier <wittmeier_at_[hidden]>
>> *Subject:* Re: [std-proposals] for-loops revision (simplification and
>> new syntax)
>>
>> Hi Simon,
>>
>> could you shortly explain the possible bug in the example given?
>>
>>
>>
>> To get the boundaries of size-1 and the >=0 correct or to avoid unsigned
>> integer underflow?
>>
>>
>>
>> auto leads to unsigned and size is 0?
>>
>>
>> -----Ursprüngliche Nachricht-----
>> *Von:* Simon Schröder via Std-Proposals <std-proposals_at_[hidden]>
>> *Gesendet:* Fr 14.02.2025 06:52
>> *Betreff:* Re: [std-proposals] for-loops revision (simplification and
>> new syntax)
>> *An:* std-proposals_at_[hidden];
>> *CC:* Simon Schröder <dr.simon.schroeder_at_[hidden]>;
>>
>> Some of the discussion now steered towards: “Is a new loop syntax useful?”
>>
>> I would prefer a syntax that leverages the existing range syntax
>> (something similar to Rust or Swift). There is probably one case where such
>> a new syntax would help avoid bugs:
>> for(std::size_t i = vec.size()-1; i >= 0; --i) …
>> i.e. counting down a loop with an unsigned integer. This might be
>> obfuscated a little more if one uses ‘auto’ to declare the loop counter.
>> With a new syntax (that also allows to specify the step size and the step
>> size can be negative) the implementation would hopefully fix this edge case.
>>
>> On Feb 13, 2025, at 10:15 PM, Sebastian Wittmeier via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>
>>
>> One should add that the *else * branch is *not *run in Python, when the
>> loop has been left with a corresponding *break *instruction.
>>
>>
>>
>>
>> -----Ursprüngliche Nachricht-----
>> *Von:* Magnus Fromreide via Std-Proposals <std-proposals_at_[hidden]
>> >
>>
>> If we are talking of loop Pythonisms then a loop else branch does add some
>> value as that case often is a bit contrieved to test for. (The else branch
>> of a loop is executed when the loop condition fails to run the loop more
>> times)
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>>
>> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
std-proposals_at_[hidden]> wrote:
> If (as has been the case whenever I've needed to this pattern before) what
> you actually need the loop to do is iterate over all valid indexes in
> reverse order, ranges has you covered already:
>
> for (std::size_t i : std::views::iota(0zu, vec.size()) |
> std::views::reverse)
>
Yup, alternatively:
for (auto&& [index, val] : views::enumerate(vec) | views::reverse)
> And if being able to define a range of integers with a custom step count
> is useful I'd suggest we'd want to instead add a third argument to iota
> before adding a new loop syntax to the core language. Although perhaps
> views::stride might already cover many of the cases you'd need a step
> count, unless you have an unsigned index that isn't a multiple of the step
> count and you're expecting overflow to cause the index go through the full
> range of the integer multiple times (although such cases would seem of
> unclear usefulness to me and seem more likely to be bugs)
>
>
> On 14 February 2025 07:16:20 GMT, Tiago Freire via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> The example is doubly bugged.
>> i>=0 is never false. And if size is 0 it size-1 overflows leading to max
>> value for the uint.
>>
>> The correct way would be.
>> for(std::size_t i = vec.size(); i-- > 0;)
>>
>> I guess the point being made is that with traditional loops, you can do
>> the wrong thing but the pattern looks good at first glance because it has
>> all the similar patterns of something that might be right when iterating
>> forwards. And it hopes to solve the same ambiguity with indexes as range
>> based for loops did with iterators.
>>
>> But again, this seems solvable without needing to add a new for loop
>> syntax.
>>
>> You could define something like:
>> for(size_t index: integer_interval(0, vec.size()))
>>
>> Or
>> for(size_t index: reverse_integer_interval(vec.size(), 0, 1))
>>
>> Where "interval" is not a list of all possible indexes, but 2 numbers
>> (start and 1 past last) that gives an iterator that counts numbers in that
>> interval.
>>
>> Would this solution work?
>>
>>
>>
>> ------------------------------
>> *From:* Std-Proposals <std-proposals-bounces_at_[hidden]> on behalf
>> of Sebastian Wittmeier via Std-Proposals <std-proposals_at_[hidden]>
>> *Sent:* Friday, February 14, 2025 7:41:25 AM
>> *To:* std-proposals_at_[hidden] <std-proposals_at_[hidden]>
>> *Cc:* Sebastian Wittmeier <wittmeier_at_[hidden]>
>> *Subject:* Re: [std-proposals] for-loops revision (simplification and
>> new syntax)
>>
>> Hi Simon,
>>
>> could you shortly explain the possible bug in the example given?
>>
>>
>>
>> To get the boundaries of size-1 and the >=0 correct or to avoid unsigned
>> integer underflow?
>>
>>
>>
>> auto leads to unsigned and size is 0?
>>
>>
>> -----Ursprüngliche Nachricht-----
>> *Von:* Simon Schröder via Std-Proposals <std-proposals_at_[hidden]>
>> *Gesendet:* Fr 14.02.2025 06:52
>> *Betreff:* Re: [std-proposals] for-loops revision (simplification and
>> new syntax)
>> *An:* std-proposals_at_[hidden];
>> *CC:* Simon Schröder <dr.simon.schroeder_at_[hidden]>;
>>
>> Some of the discussion now steered towards: “Is a new loop syntax useful?”
>>
>> I would prefer a syntax that leverages the existing range syntax
>> (something similar to Rust or Swift). There is probably one case where such
>> a new syntax would help avoid bugs:
>> for(std::size_t i = vec.size()-1; i >= 0; --i) …
>> i.e. counting down a loop with an unsigned integer. This might be
>> obfuscated a little more if one uses ‘auto’ to declare the loop counter.
>> With a new syntax (that also allows to specify the step size and the step
>> size can be negative) the implementation would hopefully fix this edge case.
>>
>> On Feb 13, 2025, at 10:15 PM, Sebastian Wittmeier via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>
>>
>> One should add that the *else * branch is *not *run in Python, when the
>> loop has been left with a corresponding *break *instruction.
>>
>>
>>
>>
>> -----Ursprüngliche Nachricht-----
>> *Von:* Magnus Fromreide via Std-Proposals <std-proposals_at_[hidden]
>> >
>>
>> If we are talking of loop Pythonisms then a loop else branch does add some
>> value as that case often is a bit contrieved to test for. (The else branch
>> of a loop is executed when the loop condition fails to run the loop more
>> times)
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>>
>> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2025-02-14 09:38:24