Mailing List Archive

RFC: Multiple-alias syntax for for
So, the plan for discussing the proposed RFC process was to feed an idea
through it, and see how we get from idea to RFC to implementation.
(Assuming that we don't reject the idea.)

About two months ago Rik had mentioned to me the idea of implementing this
(currently illegal) syntax to iterate over hashes:

for my ($key, $value) (%hash) { ... }

which isn't actually hash specific - it generalises to N-at-a-time over any
list.

I figured that the *runtime* part probably wasn't that hard, so had a crack
implementing that, assuming that I'd get help with the parser part once I
had an idea how the runtime and the optree needed to be. Except that I
didn't get stuck, and got to a complete implementation, which has been
pushed somewhere public for 6 weeks now.

( somewhere reachable in 6 clicks from https://github.com/Perl/RFCs )

So, if you have the time and skills, please try implementing something else
that would improve Perl, as re-implementing this is duplication of effort.



By chance, I started on this a couple of days before KES777 submitted
https://github.com/Perl/perl5/issues/18744
and in turn, that links to a message from Dan Brook in 2017 proposing it:
https://www.nntp.perl.org/group/perl.perl5.porters/2017/03/msg243848.html


So, rather than start on the RFC by "faking" an "idea" mail from Rik, I'll
take the genuine item from Dan:

On Fri, Mar 31, 2017 at 06:39:59PM -0400, Dan Book wrote:
> The "each" function is generally discouraged due to implementation details,
> but is still the most "pretty" and concise way to write such a loop:
>
> while (my ($key, $value) = each %hash) { ... }
>
> A possible alternative to this would be a syntax to alias multiple items
> per iteration in a for/foreach loop.
>
> foreach my ($key, $value) (%hash) { ... }
>
> This could be generalized as a "bundler", in other words to alias a number
> of elements from the list equal to the number of variables specified. Such
> as:
>
> foreach my ($foo, $bar, $baz) (@array) { # $foo, $bar, and $baz are the
> next three elements of @array, or undef if overflowed
>
> I can think of one syntactical issue presently: "foreach ($foo, $bar)"
> without the "my" is already valid syntax so would be difficult to
> disambiguate without looking for the second () denoting the list to iterate
> through.
>
> Thoughts?
>
> -Dan


This arrives here:

idea
|
v
mail p5p
|
better | rejected
on <-------?-------> with
CPAN | reasoning
v
Draft RFC
"we think this idea is worth exploring"
(Help us figure out how this will work)


For this idea, "we think this idea is worth exploring" applies, so we need
a draft.


So

1) I need to assign an ID.

Question - do I start at 0001, or keep low numbers for "something special"?
I'm guessing "start at 0001"


2) Format - PSC had thought Markdown, as many places can render it.

However,

a) github itself can render Pod. Is it the only git hosting service that can?
b) I've already found that my local markdown renderer and github disagree
about nested lists, which is annoying - how many other bugs will I hit?
c) Pod doesn't do tables, but plain markdown doesn't either.
github extended markdown with tables, but
i) How many other markdown implementations follow them?
ii) Are there alternative competing "table" dialects of Markdown?
d) I'm missing =cut


3) Who is the formal "Author" of this RFC. Does Dan want to be named?
Currently I seem to be ghost writing it, but if I become the author,
then someone else needs to take over as sponsor?
Should the copyright be Dan, and 2017?


Appended is my first draft, as if I'd only read Dan's mail.

I figure that as there has already been some discussion on github in 2021
and p5p in 2017, I should act as if that came in reply to this message,
and try taking this from here, by filling in some of the other sections.

Nicholas Clark



# Preamble

Author:
Sponsor: Nicholas Clark <nick@ccl4.org>
ID: 0001
Status: Draft
Title: Multiple-alias syntax for foreach

# Abstract

Implement the currently illegal syntax `for my ($key, $value) (%hash) { ... }` to act as two-at-a-time iteration over hashes. This approach is not specific to hashes - it generalises to n-at-a-time over any list.

# Motivation

The `each` function is generally discouraged due to implementation details, but is still the most "pretty" and concise way to write such a loop:

while (my ($key, $value) = each %hash) { ... }

An alternative to this would be a syntax to alias multiple items per iteration in a `for` loop.

for my ($key, $value) (%hash) { ... }

This generalizes as a "bundler" - to alias a number of elements from the list equal to the number of variables specified. Such as:

for my ($foo, $bar, $baz) (@array) {
# $foo, $bar, and $baz are the next three elements of @array,
# or undef if overflowed

# Rationale

The existing syntax to iterate over the keys and values of a hash:

while (my ($key, $value) = each %hash) { ... }

suffers from several problems

* For correctness it assumes that the internal state of the hash being "clean" - to be robust one should reset the iterator first with `keys %hash;` in void context
* It's hard to teach to beginners - to understand what is going on here one needs to know
- list assignment
- empty lists are false; non-empty lists are true
- that the hash holds an internal iterator
* You can't modify the hash inside the loop without confusing the iterator

The proposed syntax solves all of these.

# Specification

# Backwards Compatibility

# Security Implications

# Examples

*FIXME* - are there useful examples that aren't in the Motivation/

# Prototype Implementation

"Here's one I made earlier" applies - we already have one written, so there's no need to duplicate work

# Rejected Ideas

# Open Issues


# Copyright

Copyright (C) 2021, Nicholas Clark

This document and code and documentation within it may be used, redistributed and/or modified under the same terms as Perl itself.
Re: RFC: Multiple-alias syntax for for [ In reply to ]
This is a great example.

I support this syntax 100%. Well done.

On 6/8/2021 4:20 AM, Nicholas Clark wrote:
> So, the plan for discussing the proposed RFC process was to feed an idea
> through it, and see how we get from idea to RFC to implementation.
> (Assuming that we don't reject the idea.)
>
> About two months ago Rik had mentioned to me the idea of implementing this
> (currently illegal) syntax to iterate over hashes:
>
> for my ($key, $value) (%hash) { ... }
>
> which isn't actually hash specific - it generalises to N-at-a-time over any
> list.
>
> I figured that the *runtime* part probably wasn't that hard, so had a crack
> implementing that, assuming that I'd get help with the parser part once I
> had an idea how the runtime and the optree needed to be. Except that I
> didn't get stuck, and got to a complete implementation, which has been
> pushed somewhere public for 6 weeks now.
>
> ( somewhere reachable in 6 clicks from https://github.com/Perl/RFCs )
>
> So, if you have the time and skills, please try implementing something else
> that would improve Perl, as re-implementing this is duplication of effort.
>
>
>
> By chance, I started on this a couple of days before KES777 submitted
> https://github.com/Perl/perl5/issues/18744
> and in turn, that links to a message from Dan Brook in 2017 proposing it:
> https://www.nntp.perl.org/group/perl.perl5.porters/2017/03/msg243848.html
>
>
> So, rather than start on the RFC by "faking" an "idea" mail from Rik, I'll
> take the genuine item from Dan:
>
> On Fri, Mar 31, 2017 at 06:39:59PM -0400, Dan Book wrote:
>> The "each" function is generally discouraged due to implementation details,
>> but is still the most "pretty" and concise way to write such a loop:
>>
>> while (my ($key, $value) = each %hash) { ... }
>>
>> A possible alternative to this would be a syntax to alias multiple items
>> per iteration in a for/foreach loop.
>>
>> foreach my ($key, $value) (%hash) { ... }
>>
>> This could be generalized as a "bundler", in other words to alias a number
>> of elements from the list equal to the number of variables specified. Such
>> as:
>>
>> foreach my ($foo, $bar, $baz) (@array) { # $foo, $bar, and $baz are the
>> next three elements of @array, or undef if overflowed
>>
>> I can think of one syntactical issue presently: "foreach ($foo, $bar)"
>> without the "my" is already valid syntax so would be difficult to
>> disambiguate without looking for the second () denoting the list to iterate
>> through.
>>
>> Thoughts?
>>
>> -Dan
>
> This arrives here:
>
> idea
> |
> v
> mail p5p
> |
> better | rejected
> on <-------?-------> with
> CPAN | reasoning
> v
> Draft RFC
> "we think this idea is worth exploring"
> (Help us figure out how this will work)
>
>
> For this idea, "we think this idea is worth exploring" applies, so we need
> a draft.
>
>
> So
>
> 1) I need to assign an ID.
>
> Question - do I start at 0001, or keep low numbers for "something special"?
> I'm guessing "start at 0001"
>
>
> 2) Format - PSC had thought Markdown, as many places can render it.
>
> However,
>
> a) github itself can render Pod. Is it the only git hosting service that can?
> b) I've already found that my local markdown renderer and github disagree
> about nested lists, which is annoying - how many other bugs will I hit?
> c) Pod doesn't do tables, but plain markdown doesn't either.
> github extended markdown with tables, but
> i) How many other markdown implementations follow them?
> ii) Are there alternative competing "table" dialects of Markdown?
> d) I'm missing =cut
>
>
> 3) Who is the formal "Author" of this RFC. Does Dan want to be named?
> Currently I seem to be ghost writing it, but if I become the author,
> then someone else needs to take over as sponsor?
> Should the copyright be Dan, and 2017?
>
>
> Appended is my first draft, as if I'd only read Dan's mail.
>
> I figure that as there has already been some discussion on github in 2021
> and p5p in 2017, I should act as if that came in reply to this message,
> and try taking this from here, by filling in some of the other sections.
>
> Nicholas Clark
>
>
>
> # Preamble
>
> Author:
> Sponsor: Nicholas Clark <nick@ccl4.org>
> ID: 0001
> Status: Draft
> Title: Multiple-alias syntax for foreach
>
> # Abstract
>
> Implement the currently illegal syntax `for my ($key, $value) (%hash) { ... }` to act as two-at-a-time iteration over hashes. This approach is not specific to hashes - it generalises to n-at-a-time over any list.
>
> # Motivation
>
> The `each` function is generally discouraged due to implementation details, but is still the most "pretty" and concise way to write such a loop:
>
> while (my ($key, $value) = each %hash) { ... }
>
> An alternative to this would be a syntax to alias multiple items per iteration in a `for` loop.
>
> for my ($key, $value) (%hash) { ... }
>
> This generalizes as a "bundler" - to alias a number of elements from the list equal to the number of variables specified. Such as:
>
> for my ($foo, $bar, $baz) (@array) {
> # $foo, $bar, and $baz are the next three elements of @array,
> # or undef if overflowed
>
> # Rationale
>
> The existing syntax to iterate over the keys and values of a hash:
>
> while (my ($key, $value) = each %hash) { ... }
>
> suffers from several problems
>
> * For correctness it assumes that the internal state of the hash being "clean" - to be robust one should reset the iterator first with `keys %hash;` in void context
> * It's hard to teach to beginners - to understand what is going on here one needs to know
> - list assignment
> - empty lists are false; non-empty lists are true
> - that the hash holds an internal iterator
> * You can't modify the hash inside the loop without confusing the iterator
>
> The proposed syntax solves all of these.
>
> # Specification
>
> # Backwards Compatibility
>
> # Security Implications
>
> # Examples
>
> *FIXME* - are there useful examples that aren't in the Motivation/
>
> # Prototype Implementation
>
> "Here's one I made earlier" applies - we already have one written, so there's no need to duplicate work
>
> # Rejected Ideas
>
> # Open Issues
>
>
> # Copyright
>
> Copyright (C) 2021, Nicholas Clark
>
> This document and code and documentation within it may be used, redistributed and/or modified under the same terms as Perl itself.
>
Re: RFC: Multiple-alias syntax for for [ In reply to ]
This is actually something I prototyped a few years ago with a source
filter, I kept meaning to get around to trying to make a parser change/etc.
that actually does it in a sane way but have never had the time to properly
learn how to do it inside perl.

It was done with Keyword::Simple, and you can see it here:
https://perl.bot/p/cxj1ay

On Tue, Jun 8, 2021 at 7:21 AM Nicholas Clark <nick@ccl4.org> wrote:

> So, the plan for discussing the proposed RFC process was to feed an idea
> through it, and see how we get from idea to RFC to implementation.
> (Assuming that we don't reject the idea.)
>
> About two months ago Rik had mentioned to me the idea of implementing this
> (currently illegal) syntax to iterate over hashes:
>
> for my ($key, $value) (%hash) { ... }
>
> which isn't actually hash specific - it generalises to N-at-a-time over any
> list.
>
> I figured that the *runtime* part probably wasn't that hard, so had a crack
> implementing that, assuming that I'd get help with the parser part once I
> had an idea how the runtime and the optree needed to be. Except that I
> didn't get stuck, and got to a complete implementation, which has been
> pushed somewhere public for 6 weeks now.
>
> ( somewhere reachable in 6 clicks from https://github.com/Perl/RFCs )
>
> So, if you have the time and skills, please try implementing something else
> that would improve Perl, as re-implementing this is duplication of effort.
>
>
>
> By chance, I started on this a couple of days before KES777 submitted
> https://github.com/Perl/perl5/issues/18744
> and in turn, that links to a message from Dan Brook in 2017 proposing it:
> https://www.nntp.perl.org/group/perl.perl5.porters/2017/03/msg243848.html
>
>
> So, rather than start on the RFC by "faking" an "idea" mail from Rik, I'll
> take the genuine item from Dan:
>
> On Fri, Mar 31, 2017 at 06:39:59PM -0400, Dan Book wrote:
> > The "each" function is generally discouraged due to implementation
> details,
> > but is still the most "pretty" and concise way to write such a loop:
> >
> > while (my ($key, $value) = each %hash) { ... }
> >
> > A possible alternative to this would be a syntax to alias multiple items
> > per iteration in a for/foreach loop.
> >
> > foreach my ($key, $value) (%hash) { ... }
> >
> > This could be generalized as a "bundler", in other words to alias a
> number
> > of elements from the list equal to the number of variables specified.
> Such
> > as:
> >
> > foreach my ($foo, $bar, $baz) (@array) { # $foo, $bar, and $baz are the
> > next three elements of @array, or undef if overflowed
> >
> > I can think of one syntactical issue presently: "foreach ($foo, $bar)"
> > without the "my" is already valid syntax so would be difficult to
> > disambiguate without looking for the second () denoting the list to
> iterate
> > through.
> >
> > Thoughts?
> >
> > -Dan
>
>
> This arrives here:
>
> idea
> |
> v
> mail p5p
> |
> better | rejected
> on <-------?-------> with
> CPAN | reasoning
> v
> Draft RFC
> "we think this idea is worth exploring"
> (Help us figure out how this will work)
>
>
> For this idea, "we think this idea is worth exploring" applies, so we need
> a draft.
>
>
> So
>
> 1) I need to assign an ID.
>
> Question - do I start at 0001, or keep low numbers for "something special"?
> I'm guessing "start at 0001"
>
>
> 2) Format - PSC had thought Markdown, as many places can render it.
>
> However,
>
> a) github itself can render Pod. Is it the only git hosting service that
> can?
> b) I've already found that my local markdown renderer and github disagree
> about nested lists, which is annoying - how many other bugs will I hit?
> c) Pod doesn't do tables, but plain markdown doesn't either.
> github extended markdown with tables, but
> i) How many other markdown implementations follow them?
> ii) Are there alternative competing "table" dialects of Markdown?
> d) I'm missing =cut
>
>
> 3) Who is the formal "Author" of this RFC. Does Dan want to be named?
> Currently I seem to be ghost writing it, but if I become the author,
> then someone else needs to take over as sponsor?
> Should the copyright be Dan, and 2017?
>
>
> Appended is my first draft, as if I'd only read Dan's mail.
>
> I figure that as there has already been some discussion on github in 2021
> and p5p in 2017, I should act as if that came in reply to this message,
> and try taking this from here, by filling in some of the other sections.
>
> Nicholas Clark
>
>
>
> # Preamble
>
> Author:
> Sponsor: Nicholas Clark <nick@ccl4.org>
> ID: 0001
> Status: Draft
> Title: Multiple-alias syntax for foreach
>
> # Abstract
>
> Implement the currently illegal syntax `for my ($key, $value) (%hash) {
> ... }` to act as two-at-a-time iteration over hashes. This approach is not
> specific to hashes - it generalises to n-at-a-time over any list.
>
> # Motivation
>
> The `each` function is generally discouraged due to implementation
> details, but is still the most "pretty" and concise way to write such a
> loop:
>
> while (my ($key, $value) = each %hash) { ... }
>
> An alternative to this would be a syntax to alias multiple items per
> iteration in a `for` loop.
>
> for my ($key, $value) (%hash) { ... }
>
> This generalizes as a "bundler" - to alias a number of elements from the
> list equal to the number of variables specified. Such as:
>
> for my ($foo, $bar, $baz) (@array) {
> # $foo, $bar, and $baz are the next three elements of @array,
> # or undef if overflowed
>
> # Rationale
>
> The existing syntax to iterate over the keys and values of a hash:
>
> while (my ($key, $value) = each %hash) { ... }
>
> suffers from several problems
>
> * For correctness it assumes that the internal state of the hash being
> "clean" - to be robust one should reset the iterator first with `keys
> %hash;` in void context
> * It's hard to teach to beginners - to understand what is going on here
> one needs to know
> - list assignment
> - empty lists are false; non-empty lists are true
> - that the hash holds an internal iterator
> * You can't modify the hash inside the loop without confusing the iterator
>
> The proposed syntax solves all of these.
>
> # Specification
>
> # Backwards Compatibility
>
> # Security Implications
>
> # Examples
>
> *FIXME* - are there useful examples that aren't in the Motivation/
>
> # Prototype Implementation
>
> "Here's one I made earlier" applies - we already have one written, so
> there's no need to duplicate work
>
> # Rejected Ideas
>
> # Open Issues
>
>
> # Copyright
>
> Copyright (C) 2021, Nicholas Clark
>
> This document and code and documentation within it may be used,
> redistributed and/or modified under the same terms as Perl itself.
>
Re: RFC: Multiple-alias syntax for for [ In reply to ]
Sorry about that, I recovered the wrong old paste, this is the right one:
https://perl.bot/p/8ax2rw

On Tue, Jun 8, 2021 at 1:49 PM Ryan Voots <simcop2387@simcop2387.info>
wrote:

> This is actually something I prototyped a few years ago with a source
> filter, I kept meaning to get around to trying to make a parser change/etc.
> that actually does it in a sane way but have never had the time to properly
> learn how to do it inside perl.
>
> It was done with Keyword::Simple, and you can see it here:
> https://perl.bot/p/cxj1ay
>
> On Tue, Jun 8, 2021 at 7:21 AM Nicholas Clark <nick@ccl4.org> wrote:
>
>> So, the plan for discussing the proposed RFC process was to feed an idea
>> through it, and see how we get from idea to RFC to implementation.
>> (Assuming that we don't reject the idea.)
>>
>> About two months ago Rik had mentioned to me the idea of implementing this
>> (currently illegal) syntax to iterate over hashes:
>>
>> for my ($key, $value) (%hash) { ... }
>>
>> which isn't actually hash specific - it generalises to N-at-a-time over
>> any
>> list.
>>
>> I figured that the *runtime* part probably wasn't that hard, so had a
>> crack
>> implementing that, assuming that I'd get help with the parser part once I
>> had an idea how the runtime and the optree needed to be. Except that I
>> didn't get stuck, and got to a complete implementation, which has been
>> pushed somewhere public for 6 weeks now.
>>
>> ( somewhere reachable in 6 clicks from https://github.com/Perl/RFCs )
>>
>> So, if you have the time and skills, please try implementing something
>> else
>> that would improve Perl, as re-implementing this is duplication of effort.
>>
>>
>>
>> By chance, I started on this a couple of days before KES777 submitted
>> https://github.com/Perl/perl5/issues/18744
>> and in turn, that links to a message from Dan Brook in 2017 proposing it:
>> https://www.nntp.perl.org/group/perl.perl5.porters/2017/03/msg243848.html
>>
>>
>> So, rather than start on the RFC by "faking" an "idea" mail from Rik, I'll
>> take the genuine item from Dan:
>>
>> On Fri, Mar 31, 2017 at 06:39:59PM -0400, Dan Book wrote:
>> > The "each" function is generally discouraged due to implementation
>> details,
>> > but is still the most "pretty" and concise way to write such a loop:
>> >
>> > while (my ($key, $value) = each %hash) { ... }
>> >
>> > A possible alternative to this would be a syntax to alias multiple items
>> > per iteration in a for/foreach loop.
>> >
>> > foreach my ($key, $value) (%hash) { ... }
>> >
>> > This could be generalized as a "bundler", in other words to alias a
>> number
>> > of elements from the list equal to the number of variables specified.
>> Such
>> > as:
>> >
>> > foreach my ($foo, $bar, $baz) (@array) { # $foo, $bar, and $baz are the
>> > next three elements of @array, or undef if overflowed
>> >
>> > I can think of one syntactical issue presently: "foreach ($foo, $bar)"
>> > without the "my" is already valid syntax so would be difficult to
>> > disambiguate without looking for the second () denoting the list to
>> iterate
>> > through.
>> >
>> > Thoughts?
>> >
>> > -Dan
>>
>>
>> This arrives here:
>>
>> idea
>> |
>> v
>> mail p5p
>> |
>> better | rejected
>> on <-------?-------> with
>> CPAN | reasoning
>> v
>> Draft RFC
>> "we think this idea is worth exploring"
>> (Help us figure out how this will work)
>>
>>
>> For this idea, "we think this idea is worth exploring" applies, so we need
>> a draft.
>>
>>
>> So
>>
>> 1) I need to assign an ID.
>>
>> Question - do I start at 0001, or keep low numbers for "something
>> special"?
>> I'm guessing "start at 0001"
>>
>>
>> 2) Format - PSC had thought Markdown, as many places can render it.
>>
>> However,
>>
>> a) github itself can render Pod. Is it the only git hosting service that
>> can?
>> b) I've already found that my local markdown renderer and github disagree
>> about nested lists, which is annoying - how many other bugs will I hit?
>> c) Pod doesn't do tables, but plain markdown doesn't either.
>> github extended markdown with tables, but
>> i) How many other markdown implementations follow them?
>> ii) Are there alternative competing "table" dialects of Markdown?
>> d) I'm missing =cut
>>
>>
>> 3) Who is the formal "Author" of this RFC. Does Dan want to be named?
>> Currently I seem to be ghost writing it, but if I become the author,
>> then someone else needs to take over as sponsor?
>> Should the copyright be Dan, and 2017?
>>
>>
>> Appended is my first draft, as if I'd only read Dan's mail.
>>
>> I figure that as there has already been some discussion on github in 2021
>> and p5p in 2017, I should act as if that came in reply to this message,
>> and try taking this from here, by filling in some of the other sections.
>>
>> Nicholas Clark
>>
>>
>>
>> # Preamble
>>
>> Author:
>> Sponsor: Nicholas Clark <nick@ccl4.org>
>> ID: 0001
>> Status: Draft
>> Title: Multiple-alias syntax for foreach
>>
>> # Abstract
>>
>> Implement the currently illegal syntax `for my ($key, $value) (%hash) {
>> ... }` to act as two-at-a-time iteration over hashes. This approach is not
>> specific to hashes - it generalises to n-at-a-time over any list.
>>
>> # Motivation
>>
>> The `each` function is generally discouraged due to implementation
>> details, but is still the most "pretty" and concise way to write such a
>> loop:
>>
>> while (my ($key, $value) = each %hash) { ... }
>>
>> An alternative to this would be a syntax to alias multiple items per
>> iteration in a `for` loop.
>>
>> for my ($key, $value) (%hash) { ... }
>>
>> This generalizes as a "bundler" - to alias a number of elements from the
>> list equal to the number of variables specified. Such as:
>>
>> for my ($foo, $bar, $baz) (@array) {
>> # $foo, $bar, and $baz are the next three elements of @array,
>> # or undef if overflowed
>>
>> # Rationale
>>
>> The existing syntax to iterate over the keys and values of a hash:
>>
>> while (my ($key, $value) = each %hash) { ... }
>>
>> suffers from several problems
>>
>> * For correctness it assumes that the internal state of the hash being
>> "clean" - to be robust one should reset the iterator first with `keys
>> %hash;` in void context
>> * It's hard to teach to beginners - to understand what is going on here
>> one needs to know
>> - list assignment
>> - empty lists are false; non-empty lists are true
>> - that the hash holds an internal iterator
>> * You can't modify the hash inside the loop without confusing the iterator
>>
>> The proposed syntax solves all of these.
>>
>> # Specification
>>
>> # Backwards Compatibility
>>
>> # Security Implications
>>
>> # Examples
>>
>> *FIXME* - are there useful examples that aren't in the Motivation/
>>
>> # Prototype Implementation
>>
>> "Here's one I made earlier" applies - we already have one written, so
>> there's no need to duplicate work
>>
>> # Rejected Ideas
>>
>> # Open Issues
>>
>>
>> # Copyright
>>
>> Copyright (C) 2021, Nicholas Clark
>>
>> This document and code and documentation within it may be used,
>> redistributed and/or modified under the same terms as Perl itself.
>>
>
Re: RFC: Multiple-alias syntax for for [ In reply to ]
Cicero: The sinews of Perl are an infinite supply of CPAN.

CPAN contains many variants on this theme as shown in the example below.
Please tell me how this proposal would improve upon them well enough to
justify the immense effort of implementing this new feature in the core of
Perl?

use Test::More qw(no_plan);
use feature qw(say state current_sub);

sub forEachKeyValue(&%)
# Iterate over a hash for each key and value
{my ($body, %hash) = @_;
# Body to be executed, hash to be iterated
&$body($_, $hash{$_}) for sort keys %hash;
}

my %h = (a=>1, b=>2, c=>3);
my @t;

forEachKeyValue
{my ($letter, $number) = @_;
push @t, "Letter=$letter, number=$number";
} %h;

is_deeply join("\n", @t, ''), <<END;
Letter=a, number=1
Letter=b, number=2
Letter=c, number=3
END


On Tue, Jun 8, 2021 at 6:02 PM Scott Baker <scott@perturb.org> wrote:

> This is a great example.
>
> I support this syntax 100%. Well done.
>
> On 6/8/2021 4:20 AM, Nicholas Clark wrote:
> > So, the plan for discussing the proposed RFC process was to feed an idea
> > through it, and see how we get from idea to RFC to implementation.
> > (Assuming that we don't reject the idea.)
> >
> > About two months ago Rik had mentioned to me the idea of implementing
> this
> > (currently illegal) syntax to iterate over hashes:
> >
> > for my ($key, $value) (%hash) { ... }
> >
> > which isn't actually hash specific - it generalises to N-at-a-time over
> any
> > list.
> >
> > I figured that the *runtime* part probably wasn't that hard, so had a
> crack
> > implementing that, assuming that I'd get help with the parser part once I
> > had an idea how the runtime and the optree needed to be. Except that I
> > didn't get stuck, and got to a complete implementation, which has been
> > pushed somewhere public for 6 weeks now.
> >
> > ( somewhere reachable in 6 clicks from https://github.com/Perl/RFCs )
> >
> > So, if you have the time and skills, please try implementing something
> else
> > that would improve Perl, as re-implementing this is duplication of
> effort.
> >
> >
> >
> > By chance, I started on this a couple of days before KES777 submitted
> > https://github.com/Perl/perl5/issues/18744
> > and in turn, that links to a message from Dan Brook in 2017 proposing it:
> >
> https://www.nntp.perl.org/group/perl.perl5.porters/2017/03/msg243848.html
> >
> >
> > So, rather than start on the RFC by "faking" an "idea" mail from Rik,
> I'll
> > take the genuine item from Dan:
> >
> > On Fri, Mar 31, 2017 at 06:39:59PM -0400, Dan Book wrote:
> >> The "each" function is generally discouraged due to implementation
> details,
> >> but is still the most "pretty" and concise way to write such a loop:
> >>
> >> while (my ($key, $value) = each %hash) { ... }
> >>
> >> A possible alternative to this would be a syntax to alias multiple items
> >> per iteration in a for/foreach loop.
> >>
> >> foreach my ($key, $value) (%hash) { ... }
> >>
> >> This could be generalized as a "bundler", in other words to alias a
> number
> >> of elements from the list equal to the number of variables specified.
> Such
> >> as:
> >>
> >> foreach my ($foo, $bar, $baz) (@array) { # $foo, $bar, and $baz are the
> >> next three elements of @array, or undef if overflowed
> >>
> >> I can think of one syntactical issue presently: "foreach ($foo, $bar)"
> >> without the "my" is already valid syntax so would be difficult to
> >> disambiguate without looking for the second () denoting the list to
> iterate
> >> through.
> >>
> >> Thoughts?
> >>
> >> -Dan
> >
> > This arrives here:
> >
> > idea
> > |
> > v
> > mail p5p
> > |
> > better | rejected
> > on <-------?-------> with
> > CPAN | reasoning
> > v
> > Draft RFC
> > "we think this idea is worth exploring"
> > (Help us figure out how this will work)
> >
> >
> > For this idea, "we think this idea is worth exploring" applies, so we
> need
> > a draft.
> >
> >
> > So
> >
> > 1) I need to assign an ID.
> >
> > Question - do I start at 0001, or keep low numbers for "something
> special"?
> > I'm guessing "start at 0001"
> >
> >
> > 2) Format - PSC had thought Markdown, as many places can render it.
> >
> > However,
> >
> > a) github itself can render Pod. Is it the only git hosting service that
> can?
> > b) I've already found that my local markdown renderer and github disagree
> > about nested lists, which is annoying - how many other bugs will I
> hit?
> > c) Pod doesn't do tables, but plain markdown doesn't either.
> > github extended markdown with tables, but
> > i) How many other markdown implementations follow them?
> > ii) Are there alternative competing "table" dialects of Markdown?
> > d) I'm missing =cut
> >
> >
> > 3) Who is the formal "Author" of this RFC. Does Dan want to be named?
> > Currently I seem to be ghost writing it, but if I become the author,
> > then someone else needs to take over as sponsor?
> > Should the copyright be Dan, and 2017?
> >
> >
> > Appended is my first draft, as if I'd only read Dan's mail.
> >
> > I figure that as there has already been some discussion on github in 2021
> > and p5p in 2017, I should act as if that came in reply to this message,
> > and try taking this from here, by filling in some of the other sections.
> >
> > Nicholas Clark
> >
> >
> >
> > # Preamble
> >
> > Author:
> > Sponsor: Nicholas Clark <nick@ccl4.org>
> > ID: 0001
> > Status: Draft
> > Title: Multiple-alias syntax for foreach
> >
> > # Abstract
> >
> > Implement the currently illegal syntax `for my ($key, $value) (%hash) {
> ... }` to act as two-at-a-time iteration over hashes. This approach is not
> specific to hashes - it generalises to n-at-a-time over any list.
> >
> > # Motivation
> >
> > The `each` function is generally discouraged due to implementation
> details, but is still the most "pretty" and concise way to write such a
> loop:
> >
> > while (my ($key, $value) = each %hash) { ... }
> >
> > An alternative to this would be a syntax to alias multiple items per
> iteration in a `for` loop.
> >
> > for my ($key, $value) (%hash) { ... }
> >
> > This generalizes as a "bundler" - to alias a number of elements from the
> list equal to the number of variables specified. Such as:
> >
> > for my ($foo, $bar, $baz) (@array) {
> > # $foo, $bar, and $baz are the next three elements of @array,
> > # or undef if overflowed
> >
> > # Rationale
> >
> > The existing syntax to iterate over the keys and values of a hash:
> >
> > while (my ($key, $value) = each %hash) { ... }
> >
> > suffers from several problems
> >
> > * For correctness it assumes that the internal state of the hash being
> "clean" - to be robust one should reset the iterator first with `keys
> %hash;` in void context
> > * It's hard to teach to beginners - to understand what is going on here
> one needs to know
> > - list assignment
> > - empty lists are false; non-empty lists are true
> > - that the hash holds an internal iterator
> > * You can't modify the hash inside the loop without confusing the
> iterator
> >
> > The proposed syntax solves all of these.
> >
> > # Specification
> >
> > # Backwards Compatibility
> >
> > # Security Implications
> >
> > # Examples
> >
> > *FIXME* - are there useful examples that aren't in the Motivation/
> >
> > # Prototype Implementation
> >
> > "Here's one I made earlier" applies - we already have one written, so
> there's no need to duplicate work
> >
> > # Rejected Ideas
> >
> > # Open Issues
> >
> >
> > # Copyright
> >
> > Copyright (C) 2021, Nicholas Clark
> >
> > This document and code and documentation within it may be used,
> redistributed and/or modified under the same terms as Perl itself.
> >
>
Re: RFC: Multiple-alias syntax for for [ In reply to ]
For this specific example you can't really make one that does both the hash
iteration and multiple values from a list iteration. That said you can do
it with keywords currently from a module, see my old example that
implements essentially the entire listed behavior with Keyword::Simple

#!/usr/bin/env perl

use v5.20;

use Keyword::Simple;
use PPR;
use Data::Dumper;
use List::UtilsBy qw/bundle_by/;
use Carp;

BEGIN {
Keyword::Simple::define 'foreach', sub {
my ($ref) = @_;

# TODO make this better

my $scalar_list = qr/
\((?&PerlVariableScalar)(\s*,\s*(?&PerlVariableScalar))*\)
|
(?&PerlVariableScalar)
$PPR::GRAMMAR
/x;

my $regex = qr/\s*
(?<decl>my\s*)?(?<scalar_list>$scalar_list)
\s*
(?<input_value>(?&PerlParenthesesList))
\s*
(?<block>(?&PerlBlock))
/x;

if ($$ref =~ $regex) {

my ($input_value, $scalar_list, $block, $decl) = @+{qw/input_value
scalar_list block decl/};
# do sub here
my $scalar_count = ($scalar_list =~ y/,//)+1;

#TODO pick a non-conspicuous name for this
my $newcode = qq{
for my \$bundle (bundle_by {[\@_]} $scalar_count, $input_value)
{
$decl ($scalar_list) = \@\$bundle;

$block
}
};
my $oldcode = $$ref."";
substr $$ref, $-[0], $+[0]-$-[0], $newcode; # delete it so i see
all parsing
#warn "PARSED SUCCESS ".Data::Dumper->Dump( [\%+, $$ref, $oldcode],
[qw/captured changed orig/]);

} else {
carp "SYNTAX ERROR";
}


};
}

package main;

my %hash = (foo => 1, bar => 2);
my @array = (1,2,3, -1,-2,-3);

foreach my ($k, $v) (%hash) {
say "$k => $v";
}

foreach my ($x, $y, $z) (@array) {
say "($x, $y, $z)";
}

On Tue, Jun 8, 2021 at 2:09 PM Philip R Brenan <philiprbrenan@gmail.com>
wrote:

> Cicero: The sinews of Perl are an infinite supply of CPAN.
>
> CPAN contains many variants on this theme as shown in the example below.
> Please tell me how this proposal would improve upon them well enough to
> justify the immense effort of implementing this new feature in the core of
> Perl?
>
> use Test::More qw(no_plan);
> use feature qw(say state current_sub);
>
> sub forEachKeyValue(&%)
> # Iterate over a hash for each key and value
> {my ($body, %hash) = @_;
> # Body to be executed, hash to be iterated
> &$body($_, $hash{$_}) for sort keys %hash;
> }
>
> my %h = (a=>1, b=>2, c=>3);
> my @t;
>
> forEachKeyValue
> {my ($letter, $number) = @_;
> push @t, "Letter=$letter, number=$number";
> } %h;
>
> is_deeply join("\n", @t, ''), <<END;
> Letter=a, number=1
> Letter=b, number=2
> Letter=c, number=3
> END
>
>
> On Tue, Jun 8, 2021 at 6:02 PM Scott Baker <scott@perturb.org> wrote:
>
>> This is a great example.
>>
>> I support this syntax 100%. Well done.
>>
>> On 6/8/2021 4:20 AM, Nicholas Clark wrote:
>> > So, the plan for discussing the proposed RFC process was to feed an idea
>> > through it, and see how we get from idea to RFC to implementation.
>> > (Assuming that we don't reject the idea.)
>> >
>> > About two months ago Rik had mentioned to me the idea of implementing
>> this
>> > (currently illegal) syntax to iterate over hashes:
>> >
>> > for my ($key, $value) (%hash) { ... }
>> >
>> > which isn't actually hash specific - it generalises to N-at-a-time over
>> any
>> > list.
>> >
>> > I figured that the *runtime* part probably wasn't that hard, so had a
>> crack
>> > implementing that, assuming that I'd get help with the parser part once
>> I
>> > had an idea how the runtime and the optree needed to be. Except that I
>> > didn't get stuck, and got to a complete implementation, which has been
>> > pushed somewhere public for 6 weeks now.
>> >
>> > ( somewhere reachable in 6 clicks from https://github.com/Perl/RFCs )
>> >
>> > So, if you have the time and skills, please try implementing something
>> else
>> > that would improve Perl, as re-implementing this is duplication of
>> effort.
>> >
>> >
>> >
>> > By chance, I started on this a couple of days before KES777 submitted
>> > https://github.com/Perl/perl5/issues/18744
>> > and in turn, that links to a message from Dan Brook in 2017 proposing
>> it:
>> >
>> https://www.nntp.perl.org/group/perl.perl5.porters/2017/03/msg243848.html
>> >
>> >
>> > So, rather than start on the RFC by "faking" an "idea" mail from Rik,
>> I'll
>> > take the genuine item from Dan:
>> >
>> > On Fri, Mar 31, 2017 at 06:39:59PM -0400, Dan Book wrote:
>> >> The "each" function is generally discouraged due to implementation
>> details,
>> >> but is still the most "pretty" and concise way to write such a loop:
>> >>
>> >> while (my ($key, $value) = each %hash) { ... }
>> >>
>> >> A possible alternative to this would be a syntax to alias multiple
>> items
>> >> per iteration in a for/foreach loop.
>> >>
>> >> foreach my ($key, $value) (%hash) { ... }
>> >>
>> >> This could be generalized as a "bundler", in other words to alias a
>> number
>> >> of elements from the list equal to the number of variables specified.
>> Such
>> >> as:
>> >>
>> >> foreach my ($foo, $bar, $baz) (@array) { # $foo, $bar, and $baz are the
>> >> next three elements of @array, or undef if overflowed
>> >>
>> >> I can think of one syntactical issue presently: "foreach ($foo, $bar)"
>> >> without the "my" is already valid syntax so would be difficult to
>> >> disambiguate without looking for the second () denoting the list to
>> iterate
>> >> through.
>> >>
>> >> Thoughts?
>> >>
>> >> -Dan
>> >
>> > This arrives here:
>> >
>> > idea
>> > |
>> > v
>> > mail p5p
>> > |
>> > better | rejected
>> > on <-------?-------> with
>> > CPAN | reasoning
>> > v
>> > Draft RFC
>> > "we think this idea is worth exploring"
>> > (Help us figure out how this will work)
>> >
>> >
>> > For this idea, "we think this idea is worth exploring" applies, so we
>> need
>> > a draft.
>> >
>> >
>> > So
>> >
>> > 1) I need to assign an ID.
>> >
>> > Question - do I start at 0001, or keep low numbers for "something
>> special"?
>> > I'm guessing "start at 0001"
>> >
>> >
>> > 2) Format - PSC had thought Markdown, as many places can render it.
>> >
>> > However,
>> >
>> > a) github itself can render Pod. Is it the only git hosting service
>> that can?
>> > b) I've already found that my local markdown renderer and github
>> disagree
>> > about nested lists, which is annoying - how many other bugs will I
>> hit?
>> > c) Pod doesn't do tables, but plain markdown doesn't either.
>> > github extended markdown with tables, but
>> > i) How many other markdown implementations follow them?
>> > ii) Are there alternative competing "table" dialects of Markdown?
>> > d) I'm missing =cut
>> >
>> >
>> > 3) Who is the formal "Author" of this RFC. Does Dan want to be named?
>> > Currently I seem to be ghost writing it, but if I become the author,
>> > then someone else needs to take over as sponsor?
>> > Should the copyright be Dan, and 2017?
>> >
>> >
>> > Appended is my first draft, as if I'd only read Dan's mail.
>> >
>> > I figure that as there has already been some discussion on github in
>> 2021
>> > and p5p in 2017, I should act as if that came in reply to this message,
>> > and try taking this from here, by filling in some of the other sections.
>> >
>> > Nicholas Clark
>> >
>> >
>> >
>> > # Preamble
>> >
>> > Author:
>> > Sponsor: Nicholas Clark <nick@ccl4.org>
>> > ID: 0001
>> > Status: Draft
>> > Title: Multiple-alias syntax for foreach
>> >
>> > # Abstract
>> >
>> > Implement the currently illegal syntax `for my ($key, $value) (%hash) {
>> ... }` to act as two-at-a-time iteration over hashes. This approach is not
>> specific to hashes - it generalises to n-at-a-time over any list.
>> >
>> > # Motivation
>> >
>> > The `each` function is generally discouraged due to implementation
>> details, but is still the most "pretty" and concise way to write such a
>> loop:
>> >
>> > while (my ($key, $value) = each %hash) { ... }
>> >
>> > An alternative to this would be a syntax to alias multiple items per
>> iteration in a `for` loop.
>> >
>> > for my ($key, $value) (%hash) { ... }
>> >
>> > This generalizes as a "bundler" - to alias a number of elements from
>> the list equal to the number of variables specified. Such as:
>> >
>> > for my ($foo, $bar, $baz) (@array) {
>> > # $foo, $bar, and $baz are the next three elements of @array,
>> > # or undef if overflowed
>> >
>> > # Rationale
>> >
>> > The existing syntax to iterate over the keys and values of a hash:
>> >
>> > while (my ($key, $value) = each %hash) { ... }
>> >
>> > suffers from several problems
>> >
>> > * For correctness it assumes that the internal state of the hash being
>> "clean" - to be robust one should reset the iterator first with `keys
>> %hash;` in void context
>> > * It's hard to teach to beginners - to understand what is going on here
>> one needs to know
>> > - list assignment
>> > - empty lists are false; non-empty lists are true
>> > - that the hash holds an internal iterator
>> > * You can't modify the hash inside the loop without confusing the
>> iterator
>> >
>> > The proposed syntax solves all of these.
>> >
>> > # Specification
>> >
>> > # Backwards Compatibility
>> >
>> > # Security Implications
>> >
>> > # Examples
>> >
>> > *FIXME* - are there useful examples that aren't in the Motivation/
>> >
>> > # Prototype Implementation
>> >
>> > "Here's one I made earlier" applies - we already have one written, so
>> there's no need to duplicate work
>> >
>> > # Rejected Ideas
>> >
>> > # Open Issues
>> >
>> >
>> > # Copyright
>> >
>> > Copyright (C) 2021, Nicholas Clark
>> >
>> > This document and code and documentation within it may be used,
>> redistributed and/or modified under the same terms as Perl itself.
>> >
>>
>
Re: RFC: Multiple-alias syntax for for [ In reply to ]
Ryan,
> Sorry about that, I recovered the wrong old paste, this is the right one: https://perl.bot/p/8ax2rw
> > [N lines of text]

When replying on p5p, please be considerate of the ~500 subscribers to p5p and trim the parts of the message that you’re not directly replying to.

When you include all of a long message like that, I scan through it all, in case you’ve replied to some part of it inline, and I’m sure others will as well.

Neil
Re: RFC: Multiple-alias syntax for for [ In reply to ]
Perl already has this feature.


@triples % 3 and die "TRIPLES ARRAY NOT MULTIPLE OF 3 IN LENGTH";
while (@triples){
my ($foo, $bar, $baz) = splice @triples, 0, 3;
...
}




--
"Lay off that whiskey, and let that cocaine be!" -- Johnny Cash
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Tue, 8 Jun 2021 14:23:26 -0500
David Nicol <davidnicol@gmail.com> wrote:

> Perl already has this feature.
>
>
> @triples % 3 and die "TRIPLES ARRAY NOT MULTIPLE OF 3 IN LENGTH";
> while (@triples){
> my ($foo, $bar, $baz) = splice @triples, 0, 3;
> ...
> }

We do, but it's not very nice for two reasons:

1) DRY failure - you've written `@triples` once in the looping
condition and then a second time in the `splice`

2) It's destructive on the array

Combined, that means it's impossible to run it on any non-variable
expression, such as the result of a function call. Whereas, calling a
function is just as possible with the multivariabled foreach:

foreach my ($red, $green, $blue) (get_palette()) {
...
}

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Tue, Jun 8, 2021 at 3:35 PM Paul "LeoNerd" Evans <leonerd@leonerd.org.uk>
wrote:

> On Tue, 8 Jun 2021 14:23:26 -0500
> David Nicol <davidnicol@gmail.com> wrote:
>
> > Perl already has this feature.
> >
> >
> > @triples % 3 and die "TRIPLES ARRAY NOT MULTIPLE OF 3 IN LENGTH";
> > while (@triples){
> > my ($foo, $bar, $baz) = splice @triples, 0, 3;
> > ...
> > }
>
> We do, but it's not very nice for two reasons:
>
> 1) DRY failure - you've written `@triples` once in the looping
> condition and then a second time in the `splice`
>
> 2) It's destructive on the array
>
> Combined, that means it's impossible to run it on any non-variable
> expression, such as the result of a function call. Whereas, calling a
> function is just as possible with the multivariabled foreach:
>
> foreach my ($red, $green, $blue) (get_palette()) {
> ...
> }
>

Also it doesn't work on hashes.

-Dan
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Tue, 8 Jun 2021 at 13:21, Nicholas Clark <nick@ccl4.org> wrote:

> So, the plan for discussing the proposed RFC process was to feed an idea
> through it, and see how we get from idea to RFC to implementation.
> (Assuming that we don't reject the idea.)
>
> About two months ago Rik had mentioned to me the idea of implementing this
> (currently illegal) syntax to iterate over hashes:
>
> for my ($key, $value) (%hash) { ... }
>
>
Alternative proposal (as part of more complex proposal I'm preparing, based
on https://gist.github.com/happy-barney/d94d3a6d30b4529ab86ef5ea6c78a043)
Just as code samples

# iterate by two elements, die odd number of numbers
for (@list) {
has ($key, $value);
}

# iterate by three elements, use default values if @list % 3 != 0
for (@list) {
has $first;
has $second := :default => 'foo';
has $third := :default => 'bar';
}

# iterate over keys only
for (%hash) {
has $key := :is => HASH::key;
}

# iterate over list with index
for (@list) {
has $index := :is => ARRAY::index;
has $value;
}
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Tue, Jun 08, 2021 at 03:50:07PM -0400, Dan Book wrote:
> On Tue, Jun 8, 2021 at 3:35 PM Paul "LeoNerd" Evans <leonerd@leonerd.org.uk>
> wrote:
>
> > On Tue, 8 Jun 2021 14:23:26 -0500
> > David Nicol <davidnicol@gmail.com> wrote:
> >
> > > Perl already has this feature.

Your statement "has this feature" is not accurate. What you show below
is using existing functionality (features, *plural*) to implement the
behaviour.

What you mean is "Perl does not need a special feature for this because it
can be implemented with existing features".

Which in itself is a sensible argument against adding a feature.

Trouble is, that Perl is a Turing complete language. Meaning that *any*
possible new feature that could be proposed can already be implemented with
existing functionality.

So arguing against a new feature because it is already possible is, well,
tautological.


So, I assume that what you are really trying to argue is:

Perl does not need a special feature for this because it can be *easily*
be implemented with existing features.


Which gets us to:

> > > @triples % 3 and die "TRIPLES ARRAY NOT MULTIPLE OF 3 IN LENGTH";
> > > while (@triples){
> > > my ($foo, $bar, $baz) = splice @triples, 0, 3;
> > > ...
> > > }
> >
> > We do, but it's not very nice for two reasons:
> >
> > 1) DRY failure - you've written `@triples` once in the looping
> > condition and then a second time in the `splice`
> >
> > 2) It's destructive on the array
> >
> > Combined, that means it's impossible to run it on any non-variable
> > expression, such as the result of a function call. Whereas, calling a
> > function is just as possible with the multivariabled foreach:
> >
> > foreach my ($red, $green, $blue) (get_palette()) {
> > ...
> > }
> >
>
> Also it doesn't work on hashes.

Or efficiently on things like ranges. The syntax (1..9999999) doesn't
actually generate a temporary list of 9,999,999 items:

$ ./perl -Ilib -MO=Concise,-exec -e 'for my $c (1..9999999) { ... } '
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <0> pushmark s
4 <$> const(IV 1) s
5 <$> const(IV 9999999) s
6 <{> enteriter(next->b last->e redo->7)[$c:2,5] vKS/LVINTRO
c <0> iter s
d <|> and(other->7) vK/1
7 <;> nextstate(main 4 -e:1) v
8 <0> pushmark s
9 <$> const(PV "Unimplemented") s
a <@> die vK/1
b <0> unstack v
goto c
e <2> leaveloop vK/2
f <@> leave[1 ref] vKP/REFC
-e syntax OK


The approach your suggesting would require creating a temporary array to
hold the contents of the list (or hash, or array you don't want to destroy)
- this is a bunch of copying that the direct syntax avoids.

I *think* that one could use a loop like this to avoid the destructive splice:

for (my $i = 0; $i < @array; $i += 3) {
my ($foo, $bar, $baz) = @array[$i .. $i + 2];
...
}

but I've deliberately *not* tested that, as my point is that there are
several things that I know that I might get wrong here (boundary cases in
the for loop, boundary cases in the list slice) - it's "no obvious bugs"

Whereas the proposed syntax is

for my ($foo, $bar, $baz) (@array) {
...
}

"obviously no bugs" (famous last words)


Finally, foreach *aliases* its iterator - if the loop actually wants to
modify the values in-place, any "copying" approach isn't going to solve the
programmer's problem easily.


This gets back to the non-tautological argument:

Perl does not need a special feature for this because it can be *easily*
be implemented with existing features.


I don't think that this is true.

The existing approaches are more verbose, and have many ways to make
mistakes.

Nicholas Clark
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Tue, Jun 08, 2021 at 07:09:20PM +0100, Philip R Brenan wrote:
> Cicero: The sinews of Perl are an infinite supply of CPAN.
>
> CPAN contains many variants on this theme as shown in the example below.
> Please tell me how this proposal would improve upon them well enough to
> justify the immense effort of implementing this new feature in the core of
> Perl?

"immense effort"

Down in the part that everyone quoted, but didn't seem to read:

> > > # Prototype Implementation
> > >
> > > "Here's one I made earlier" applies - we already have one written, so
> > there's no need to duplicate work

I believe that it took me about 3 days to implement this.

By the standards of what it would take to implement some of the language
changes I've seen proposed, that is trivial.

Moreover, it's relatively self contained, so relatively low risk.

Runtime changes are in one function in one file:

$ git diff -w --stat fd11779cdb4d6f04f5f869d890845a060b696bba pp_hot.c
1 file changed, 80 insertions(+), 19 deletions(-)

optree generation changes are small:

$ git diff -w --stat fd11779cdb4d6f04f5f869d890845a060b696bba op.c
1 file changed, 62 insertions(+), 4 deletions(-)

Grammar changes are small:

$ git diff --stat fd11779cdb4d6f04f5f869d890845a060b696bba perly.y
1 file changed, 20 insertions(+), 1 deletion(-)


One doesn't *need* sufficient knowledge to implement changes to be able to
discuss whether the trade offs are worth it, but one does need a good
*feel* for what is hard/what is not, before passing judgement on the
risk/reward of an idea. I didn't set off knowing that it would be exactly
this small, but I had an idea that likely it would be, because I knew
what shape the runtime code for `for` has (and it's not very large.)



As to your suggestion:

> sub forEachKeyValue(&%)
> # Iterate over a hash for each key and value
> {my ($body, %hash) = @_;
> # Body to be executed, hash to be iterated
> &$body($_, $hash{$_}) for sort keys %hash;
> }
>
> my %h = (a=>1, b=>2, c=>3);
> my @t;
>
> forEachKeyValue
> {my ($letter, $number) = @_;
> push @t, "Letter=$letter, number=$number";
> } %h;


Right now, if I need to iterate over key and value combined, I'm tempted
to write:

for my $k (keys %hash) {
my $v = $hash{$h};
...
}


That's a lot fewer lines than your suggestion, and doesn't *copy* the entire
hash, avoids a lot of function calls, and I can choose whether I want to
sort or not.

Yes, it works.

But it doesn't generalise to n-at-a-time iteration over arbitrary lists (or
arrays), which the proposed syntax does.

Nicholas Clark
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Tue, Jun 08, 2021 at 09:55:23PM +0200, Branislav Zahradn?k wrote:
> On Tue, 8 Jun 2021 at 13:21, Nicholas Clark <nick@ccl4.org> wrote:
>
> > So, the plan for discussing the proposed RFC process was to feed an idea
> > through it, and see how we get from idea to RFC to implementation.
> > (Assuming that we don't reject the idea.)
> >
> > About two months ago Rik had mentioned to me the idea of implementing this
> > (currently illegal) syntax to iterate over hashes:
> >
> > for my ($key, $value) (%hash) { ... }
> >
> >
> Alternative proposal (as part of more complex proposal I'm preparing, based
> on https://gist.github.com/happy-barney/d94d3a6d30b4529ab86ef5ea6c78a043)
> Just as code samples
>
> # iterate by two elements, die odd number of numbers
> for (@list) {
> has ($key, $value);
> }
>
> # iterate by three elements, use default values if @list % 3 != 0
> for (@list) {
> has $first;
> has $second := :default => 'foo';
> has $third := :default => 'bar';
> }
>
> # iterate over keys only
> for (%hash) {
> has $key := :is => HASH::key;
> }

I'm not sure what that wins over the existing

for my $key (keys %hash) {
}

and using your `has` approach the key/value pairing could be written as

# iterate by two elements, die odd number of numbers
for (%hash) {
has ($key, $value);
}

relying on existing list flattening.

I appreciate that this is syntax that is intended to be massively more
flexible, but it's conjectured on several things that aren't yet designed,
let alone implemented

* `has` for class attributes
* extending `has` more generally (here, for blocks)
* variable binding syntax `:=`
* some level of auto-boxing on HASHes, or a HASH namespace that behaves in
"interesting" ways with the parser.

I think that this could make sense once Cor is in the core, but unlike the
proposal, it's not something that we could have land next week - it's part
of a much bigger (coherent) design, that isn't firm yet.


Also, this is Perl - "There's More Than One Way To Do It" is acceptable.
("But I hesitate to make ten" also applies).

The two syntaxes for the same thing can coexist in the future - one is
"easy things easy", the other enables "hard things possible".


We don't need to get into a tailspin about "which is more Pythonic".
We can have both. Having one doesn't rule out the other.

(This seems to be what happens on Stack Overflow etc as soon as it becomes
apparent that there are multiple reasonable solutions to a problem, and
hence it is axiomatic that is necessary to figure out which is unequivocally
best.)

Nicholas Clark
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Tue, 8 Jun 2021 11:20:57 +0000
Nicholas Clark <nick@ccl4.org> wrote:

> About two months ago Rik had mentioned to me the idea of implementing this
> (currently illegal) syntax to iterate over hashes:
>
> for my ($key, $value) (%hash) { ... }
>
> which isn't actually hash specific - it generalises to N-at-a-time over any
> list.

I love this feature, it's something I've been really missing in Perl.
Also, I'm really glad we finally have an RFC process :)

> 2) Format - PSC had thought Markdown, as many places can render it.
>
> However,
>
> a) github itself can render Pod. Is it the only git hosting service that can?
> b) I've already found that my local markdown renderer and github disagree
> about nested lists, which is annoying - how many other bugs will I hit?
> c) Pod doesn't do tables, but plain markdown doesn't either.
> github extended markdown with tables, but
> i) How many other markdown implementations follow them?
> ii) Are there alternative competing "table" dialects of Markdown?
> d) I'm missing =cut

Personally, I'm in favor of POD, dogfooding FTW. I don't know about the
other git hosting services, but why does it matter? We are using Github.
Re: RFC: Multiple-alias syntax for for [ In reply to ]
Den 08.06.2021 13:20, skrev Nicholas Clark:
> So, the plan for discussing the proposed RFC process was to feed an idea
> through it, and see how we get from idea to RFC to implementation.
> (Assuming that we don't reject the idea.)
>
> About two months ago Rik had mentioned to me the idea of implementing this
> (currently illegal) syntax to iterate over hashes:
>
> for my ($key, $value) (%hash) { ... }

I'm sorry if this is the wrong place to comment, but I see several
comments about the proposition itself, so here goes:

I really like this, it makes life simpler.

I was wondering though:

1) since it looks like such an obvious improvement but hasn't been done
before, is there some reason that one hasn't gone down this route
before? Are there some hidden gotchas about it? Or is it just genius
overlooked simplification?

2) will this work flawlessly with for instance: for my ($key $value,
%rest) = (%hash) { … } (iterating only once)

3) will it work transparently with foreach (I believe I saw some
comments about that)

If there is a more suitable place to ask these questions or comment,
please enlighten me.

--

Nicolas Mendoza
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Wed, Jun 9, 2021 at 7:44 PM Nicolas Mendoza <mendoza@pvv.ntnu.no> wrote:

>
> 1) since it looks like such an obvious improvement but hasn't been done
> before, is there some reason that one hasn't gone down this route
> before? Are there some hidden gotchas about it? Or is it just genius
> overlooked simplification?
>

I suspect no proposal has gotten far enough in implementation yet to be
usefully discussed.


> 2) will this work flawlessly with for instance: for my ($key $value,
> %rest) = (%hash) { … } (iterating only once)
>

I don't see why this should be supported and complicate the implementation,
since you can just do that assignment without any loop.


> 3) will it work transparently with foreach (I believe I saw some
> comments about that)
>

Not sure what you mean; this is a feature specifically for foreach.

-Dan
Re: RFC: Multiple-alias syntax for for [ In reply to ]
Den 10.06.2021 03:37, skrev Dan Book:
>
> 2) will this work flawlessly with for instance: for my ($key $value,
> %rest) = (%hash) { … } (iterating only once)
>
>
> I don't see why this should be supported and complicate
> the implementation, since you can just do that assignment without any
> loop.

I see I wrote the wrong syntax, I meant that since it is supposed to
work n-at-a-time, what would it do when having a hash or an array on the
left side. Would it behave similar to constructs not in a for-loop like
classical argument assignment (my ($self, $in, %opt) = @_; or just die?

for my ($key, $value, %rest) (%hash) { … } # one iteration or syntax error?

for my ($first, $second, @rest) (@array) { … } # one iteration or syntax
error?

for my ($a, $b, $c) (@array) { … } # int($#array / 3) + ($#array % 3)
iterations?

for my (@a) (@array) { … } # one iteration or syntax error

for my ($a, $b, undef) ((1,2,3)) { … } # one iteration or syntax error--

--

Nicolas Mendoza
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, Jun 10, 2021 at 01:43:43AM +0200, Nicolas Mendoza wrote:
>
> Den 08.06.2021 13:20, skrev Nicholas Clark:
> > So, the plan for discussing the proposed RFC process was to feed an idea
> > through it, and see how we get from idea to RFC to implementation.
> > (Assuming that we don't reject the idea.)
> >
> > About two months ago Rik had mentioned to me the idea of implementing this
> > (currently illegal) syntax to iterate over hashes:
> >
> > for my ($key, $value) (%hash) { ... }
>
> I'm sorry if this is the wrong place to comment, but I see several comments
> about the proposition itself, so here goes:

No, this is totally the right place to comment.

It's sensible comments like this (particularly comments from people whose
names I don't recognise) that we'd like to see.

> I really like this, it makes life simpler.

That was what I thought when I first saw the idea. But I'm not sure if I'm
biased. :-)

On Wed, Jun 09, 2021 at 09:37:42PM -0400, Dan Book wrote:
> On Wed, Jun 9, 2021 at 7:44 PM Nicolas Mendoza <mendoza@pvv.ntnu.no> wrote:
>
> >
> > 1) since it looks like such an obvious improvement but hasn't been done
> > before, is there some reason that one hasn't gone down this route
> > before? Are there some hidden gotchas about it? Or is it just genius
> > overlooked simplification?
> >
>
> I suspect no proposal has gotten far enough in implementation yet to be
> usefully discussed.

I really don't know.

I'm going to guess that it's a few things

1) historically to get something implemented required some luck - it needed
an idea to arrive with someone who stood a chance of implementing it
(this is still true, I guess)
And most of those people already have a bunch more ideas that they'd like
to try than time to do it. So
i) either *they* have to have this great idea and start work on it
ii) someone else has to have an idea *so* great that it's better than any
of their ideas, and they drop their other free-time plans

2) I re-read the previous discussions - as ever, some people said
"I don't think that this is useful enough" whereas others said
"that seems cool", but there wasn't an "executive" decision made to
conclude the discussion. So it hangs as "maybe".
In particular there isn't an affirmative "if you did put the effort into
trying to implement this, it will be accepted". A policy decision isn't
made - any work you do is at risk of being ignore

3) When Rik mentioned the basic idea to me about two months ago, he knew that
the syntax was "low risk" - it fits in nicely and is currently an error.
I was far more enthusiastic than he expected because I had some idea that
the runtime was *also* "low risk" - get the internal data structures right
and code changes would only be needed in one OP. So it looked "easy", and
seemed like a good surprise to launch a future (likely) 5.36.0 with,
given that we expected 5.34.0 to be a bit low key.

which is how we ended up with me hacking up implementation over a weekend
and a bit, about 6 weeks ago. And then we had to sit on it...


During which time I figured out that (1) I really wanted an RFC process
(2) Heck, there were still some unanswered questions in what I did, and
given that we'd have to answer them anyway, why not *use* this idea to
test the RFC process, and see if it can answer the questions.

You've actually sort of hit on one of the questions (well, one of the
implementation assumptions I made).

> > 3) will it work transparently with foreach (I believe I saw some
> > comments about that)
> >
>
> Not sure what you mean; this is a feature specifically for foreach.

Other folks know (or at least understand) the grammar better than me.
I *think* that `for` and `foreach` are aliases for the same thing. In that,
they are two spellings of the same keyword and once they have been parsed
they are identical.

I admit some guilt and inconsistency here - *I* preferred using `for` in
the code examples because it's 4 characters shorter.

*but* I realised that that makes the title `Multiple-alias syntax for for`
which is daft. So I changed *that* to `foreach`. And now it's inconsistent.
Bad programmer, no cookie.

I don't know what is best.

On Thu, Jun 10, 2021 at 04:00:45AM +0200, Nicolas Mendoza wrote:
>
> Den 10.06.2021 03:37, skrev Dan Book:
> >
> > 2) will this work flawlessly with for instance: for my ($key $value,
> > %rest) = (%hash) { … } (iterating only once)
> >
> >
> > I don't see why this should be supported and complicate
> > the implementation, since you can just do that assignment without any
> > loop.
>
> I see I wrote the wrong syntax, I meant that since it is supposed to work
> n-at-a-time, what would it do when having a hash or an array on the left
> side. Would it behave similar to constructs not in a for-loop like classical
> argument assignment (my ($self, $in, %opt) = @_; or just die?
>
> for my ($key, $value, %rest) (%hash) { … } # one iteration or syntax error?

Syntax error.

> for my ($first, $second, @rest) (@array) { … } # one iteration or syntax
> error?

Syntax error.

> for my ($a, $b, $c) (@array) { … } # int($#array / 3) + ($#array % 3)
> iterations?

This is a question that has to be decided...

What happens here if the list count isn't an integer multiple of 3?

To me, the most obvious answer was substitute undef if it's not
(ie don't die, and don't ignore what would be incomplete 'tuples' at the end)

So if the list has 10 elements, it iterates as

One Two Three
Four Five Six
Seven Eight Nine
Ten undef undef

and with 11, that last iteration is

Ten Eleven undef

> for my (@a) (@array) { … } # one iteration or syntax error

Syntax error. You can only have scalars

> for my ($a, $b, undef) ((1,2,3)) { … } # one iteration or syntax error--

Right. This is the interesting question...

I'm suggesting syntax error.

I think the slightly better question would be express it as

for my ($a, undef, $c) (1 .. 9) { ... }


It's a reasonable generalisation of list assignment, where you can assign to
undef to mean "ignore this value". I can see that this *might* be useful.
It's also safe syntax to implement (although I didn't try, and I'm not sure
how hard it would be).

I'd like to stick to forbidding this, because it makes the implementation
harder.


So, the sort of dirty secret/insight...


The thing I knew before I started was that the code to "get the next
iteration item or terminate the loop" is fairly simple, and really the
only thing that needs changing to go from "1 at a time" to "n at a time".

Also, one might think that Perl internally is a stack machine, but it's
actually sort of hybrid, as many ops can access the Pads directly.
Pads are arrays of (pointers to) SVs - ops store the index of an entry
in the Pad, so arguably this is kind of a register machine.

Rik knew that the syntax only makes sense for a list of lexicals, because
the `my` at that point is a syntax error.

The background is that the perl parser has to know what it is parsing as it
parses it. This syntax:

for ($key, $value) (%hash) { ... }

^
isn't going to work, because at this point the parser things that it has
parsed the list *that is being iterated over* (and done stuff that has
committed itself to this interpretation), meaning that when it sees '('
and not '{' it can't backtrack and change its mind - this is beyond it.

So, that `my (` is all key here - it's currently a syntax error, but making
the `(` legal after `my` lets the grammar know that what is next is a list
of iterator targets.

[.The above part is stuff other people have explained to me.]

The insight I had was that *if* the only thing you allow for "n at time"
iteration is a list of *newly declared lexicals*, then they all sit in
adjacent pad slots.

Right now, this syntax:

for my $key (keys %hash) { ... }

allocates a pad slot for $key, and stores the numeric index of that pad slot
in (actually) the enteriter op. (This was a surprise - the more logical
place would seem to be the iter op):

$ ./perl -Ilib -MO=Concise,-exec -e 'for my $key (keys %hash) { ... }'
1 <0> enter v
2 <;> nextstate(main 1 -e:1) v:{
3 <0> pushmark sM
4 <$> gv(*hash) s
5 <1> rv2hv[t2] lKRM
6 <1> keys[t3] lKM/1
7 <{> enteriter(next->c last->f redo->8)[$key:2,5] vK/LVINTRO
d <0> iter s
e <|> and(other->8) vK/1
8 <;> nextstate(main 4 -e:1) v
9 <0> pushmark s
a <$> const(PV "Unimplemented") s
b <@> die vK/1
c <0> unstack v
goto d
f <2> leaveloop vK/2
g <@> leave[1 ref] vKP/REFC
-e syntax OK


OK, so, if you permit 3-at-a-time iteration, at first glance that seems to
mean that you now need to store 3 pad slots, not 1, and where is there space
to "hide" 2 more integers?

But as long as you are declaring $n lexicals and iterating over $n lexicals,
then you have them in the next slots (ie (1 .. $n - 1)), meaning that you
now only have to find space to store one other integer - it's the "count of
how many we are iterating" - the addresses of the variables to use as
iterators can all be calculated from the known location of the first
variable.

So, it's a lot easier to implement (and a bit faster too, and less likely to
be buggy) if we don't permit undef in the iteration list. And I'd prefer to
keep it that way, at least to start with.


So thanks for asking the right question...

Nicholas Clark
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, Jun 10, 2021 at 07:28:16AM +0000, Nicholas Clark wrote:
> On Thu, Jun 10, 2021 at 01:43:43AM +0200, Nicolas Mendoza wrote:

> > I'm sorry if this is the wrong place to comment, but I see several comments
> > about the proposition itself, so here goes:
>
> No, this is totally the right place to comment.

And after a coffee, I realise that this is how I think the RFC process
should work. In that

1) this discussion should be summarised in the RFC itself
2) the Author should do this

So as (ghost author) for this RFC, I pushed the appended commit.

Nicholas Clark

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

commit 50e30612a2fc96a2d20b050ab450cc5bfc98c429 (HEAD -> master)
Author: Nicholas Clark <nick@ccl4.org>
Date: Thu Jun 10 09:57:35 2021 +0200

Record why permitting `undef` in the list of scalars is a rejected idea.

Also record explicitly why permitting hashes and arrays isn't worth it.

This explanation prompted by Nicolas Mendoza asking useful questions.

diff --git a/rfcs/rfc0001.md b/rfcs/rfc0001.md
index f2c812f..b93b17e 100644
--- a/rfcs/rfc0001.md
+++ b/rfcs/rfc0001.md
@@ -52,7 +52,7 @@ The proposed syntax solves all of these.

## Examples

-*FIXME* - are there useful examples that aren't in the Motivation/
+*FIXME* - are there useful examples that aren't in the Motivation?

## Prototype Implementation

@@ -60,6 +60,28 @@ The proposed syntax solves all of these.

## Rejected Ideas

+### Permit `undef` in the list of scalars
+
+ for my ($a, undef, $c) (1 .. 9) { ... }
+
+It's a reasonable generalisation of list assignment, where you can assign to undef to mean "ignore this value". I can see that this **might** be useful. It's also safe syntax to implement (although I didn't try, and I'm not sure how hard it would be).
+
+But it adds considerable runtime complexity. The easiest implementation is if there are exactly *n* scalars, all declared in the `for` loop itself, because this way they occupy adjacent Pad slots. This means that there is only one extra integer to store in the optree, which used both to calculate the *n*-at-a-time **and** the addresses of the target variables.
+
+Adding `undef` to the mix rules out a simple, clear implementation.
+
+### Permit @array or %hash in the list of lexicals
+
+ for my ($key, $value, %rest) (%hash) { ... }
+ for my ($first, $second, @rest) (@array) {... }
+
+Syntactically these all "work", and don't violate the assumption that all lexicals are in adjacent Pad slots. But it would add complexity to the runtime. Generalising *1 scalar at a time* to *n at a time* is mostly just adding a C `for` loop around some existing (known working) code.
+
+Implementing these would mean adding code for what is basically a funky way of writing
+
+ { my ($key, $value, %rest) = %hash; ... }
+ { my ($first, $second, @rest) = @array; ... }
+
## Open Issues
Re: RFC: Multiple-alias syntax for for [ In reply to ]
> for my ($key, $value) (%hash) { ... }

Could:

for my ($index, $value) (@array) { ... }

... be in the cards?

I always find it tiring to have to iterate by index using a weird:

for my $i (0..$#array) {
my $value = $array[$i];
# ...

... and I'd rather the golang way (unsure if other languages have it)
of being able to iterate either by value, or key/value for
maps/hashes, or index/value for arrays, specifically.

--
Marco Fontani
+39-329-2180550
perl -E'say v74.65.80.72'
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, Jun 10, 2021 at 3:28 AM Nicholas Clark <nick@ccl4.org> wrote:

>
> I admit some guilt and inconsistency here - *I* preferred using `for` in
> the code examples because it's 4 characters shorter.
>
> *but* I realised that that makes the title `Multiple-alias syntax for for`
> which is daft. So I changed *that* to `foreach`. And now it's inconsistent.
> Bad programmer, no cookie.
>
> I don't know what is best.
>

My preference is to refer to the syntax construct descriptively as
"foreach", since although it is an exact synonym in the grammar, the
C-style for loop is never referred to as a "foreach". Separately from what
any person may decide to write in the actual code.


> > for my ($a, $b, $c) (@array) { … } # int($#array / 3) + ($#array % 3)
> > iterations?
>
> This is a question that has to be decided...
>
> What happens here if the list count isn't an integer multiple of 3?
>
> To me, the most obvious answer was substitute undef if it's not
> (ie don't die, and don't ignore what would be incomplete 'tuples' at the
> end)
>
> So if the list has 10 elements, it iterates as
>
> One Two Three
> Four Five Six
> Seven Eight Nine
> Ten undef undef
>
> and with 11, that last iteration is
>
> Ten Eleven undef
>

This was my assumption as well and seems the most reasonable thing to do.
It's consistent with regular list assignment.


> > for my ($a, $b, undef) ((1,2,3)) { … } # one iteration or syntax error--
>
> Right. This is the interesting question...
>
> I'm suggesting syntax error.
>
> I think the slightly better question would be express it as
>
> for my ($a, undef, $c) (1 .. 9) { ... }
>
>
> It's a reasonable generalisation of list assignment, where you can assign
> to
> undef to mean "ignore this value". I can see that this *might* be useful.
> It's also safe syntax to implement (although I didn't try, and I'm not sure
> how hard it would be).
>
> I'd like to stick to forbidding this, because it makes the implementation
> harder.
>

I also see how it could be useful, but on the other hand it is exactly the
same in practice as my ($x, $y, $z) but with some (imagined or real)
microoptimization of not aliasing the second value/using up that variable
name. I don't think it's useful enough to outweigh complication to the
implementation.

-Dan
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, Jun 10, 2021 at 4:20 AM Marco Fontani <fontani@gmail.com> wrote:

> > for my ($key, $value) (%hash) { ... }
>
> Could:
>
> for my ($index, $value) (@array) { ... }
>
> ... be in the cards?
>
> I always find it tiring to have to iterate by index using a weird:
>
> for my $i (0..$#array) {
> my $value = $array[$i];
> # ...
>
> ... and I'd rather the golang way (unsure if other languages have it)
> of being able to iterate either by value, or key/value for
> maps/hashes, or index/value for arrays, specifically.
>

Not likely, because this would already have the meaning of iterating over
the array 2 elements at a time. You could do something like:

foreach my ($i, $elem) (%array[0..$#array]) {

Up to you whether you think that's more understandable...

-Dan
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, 10 Jun 2021 10:20:09 +0200, Marco Fontani <fontani@gmail.com>
wrote:

> > for my ($key, $value) (%hash) { ... }
>
> Could:
>
> for my ($index, $value) (@array) { ... }
>
> ... be in the cards?
>
> I always find it tiring to have to iterate by index using a weird:
>
> for my $i (0..$#array) {
> my $value = $array[$i];
> # ...

This is already supported by `each`:

$ perl -wE'my@x="a".."f";while(my($idx,$v)=each@x){say"$idx:$v"}'
0:a
1:b
2:c
3:d
4:e
5:f

> ... and I'd rather the golang way (unsure if other languages have it)
> of being able to iterate either by value, or key/value for
> maps/hashes, or index/value for arrays, specifically.

--
H.Merijn Brand https://tux.nl Perl Monger http://amsterdam.pm.org/
using perl5.00307 .. 5.33 porting perl5 on HP-UX, AIX, and Linux
https://tux.nl/email.html http://qa.perl.org https://www.test-smoke.org
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, Jun 10, 2021 at 10:20:09AM +0200, Marco Fontani wrote:
> > for my ($key, $value) (%hash) { ... }
>
> Could:
>
> for my ($index, $value) (@array) { ... }
>
> ... be in the cards?

Not with *that* syntax, because that conflicts with general n-at-a-time.

But it's a problem that needs solving well, and I hope there will be an RFC
about it soon.

(The would-be author is currently asleep, so I can't confirm or deny
anything. I might be jumping the gun here, but there's a syntax suggestion
that builds on n-at-a-time to implement what you want. I hope I haven't
let too much slip, but I wanted to reply promptly.)

Nicholas Clark

1 2 3  View All