develooper Front page | perl.perl5.porters | Postings from June 2021

RFC: Multiple-alias syntax for for

Thread Next
From:
Nicholas Clark
Date:
June 8, 2021 11:21
Subject:
RFC: Multiple-alias syntax for for
Message ID:
20210608112057.GQ16703@etla.org
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.

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About