Mailing List Archive

1 2 3  View All
Re: RFC: Multiple-alias syntax for for [ In reply to ]
From the keyboard of Dan Book [10.06.21,04:24]:

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

And it would introduce an exception of a general rule for little gain.
Targets for assignments must be lvalues. Assigning to undef, a literal
or a constant is prohibited.

If assigning to 'undef' in that special case is permitted, the following
should also be permitted

for my ($first, "banana", $last) (@snacks) { ... }

and so the "must be lvalue" rule would deteriorate from that end.

0--gg-

--
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, 10 Jun 2021 08:27:54 +0000
Nicholas Clark <nick@ccl4.org> wrote:

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

I've often pondered stealing Python's "enumerate" function; so that
would be


foreach my ($index, $item) (enumerate @array)
{
...
}

Where `enumerate LIST` just yields (0, LIST[0], 1, LIST[1], ...)

--
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 Thu, Jun 10, 2021 at 4:46 AM shmem <gm@qwurx.de> wrote:

> From the keyboard of Dan Book [10.06.21,04:24]:
>
> > > 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.
>
> And it would introduce an exception of a general rule for little gain.
> Targets for assignments must be lvalues. Assigning to undef, a literal
> or a constant is prohibited.
>
> If assigning to 'undef' in that special case is permitted, the following
> should also be permitted
>
> for my ($first, "banana", $last) (@snacks) { ... }
>
> and so the "must be lvalue" rule would deteriorate from that end.


Well, it is already a special case in list assignment for this purpose,
which is probably where the idea came from:

my ($x, undef, $z) = @stuff;

But so are a bunch of other things that don't make sense in this context.

-Dan
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On 10/6/21 10:06, Nicholas Clark wrote:

>
> +### 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.

Can you just add a dummy variable there so that internally

for my ($foo, undef, $bar) (@a) {...}

is converted in something similar to

for my ($foo, $hidden_variable, $bar) (@a) {...}

?

Just for the sake of being consistent.
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, Jun 10, 2021 at 11:16:25AM +0200, Salvador Fandi?o wrote:
> On 10/6/21 10:06, Nicholas Clark wrote:
>
> >
> > +### 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.
>
> Can you just add a dummy variable there so that internally
>
> for my ($foo, undef, $bar) (@a) {...}
>
> is converted in something similar to
>
> for my ($foo, $hidden_variable, $bar) (@a) {...}

Yes, I think it would be possible, and probably the simplest solution.
It added complication. *I* didn't want to, as it added complication.

> ?
>
> Just for the sake of being consistent.

Yes, this is a trade off. *I* didn't think that it was worth it.
I'm not familiar enough with the grammar generally to know how to do this
easily, and I think that the optree generation would also become more
complicated.

Given that we already forbid arrays and hashes in the list of lexicals
we are declaring, it's already "inconsistent" with what my (...) = (...);
permits, so I'm not sure if we really are removing inconsistency if we
did the work to permit undef too.

Yes, this is subjective. And I might not be correct.

Nicholas Clark
Re: RFC: Multiple-alias syntax for for [ In reply to ]
Op 10-06-2021 om 09:28 schreef Nicholas Clark:
> 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. :-)
>

FWIW, I love it too. I would use this all the time. Also, it feels so
perlish, as others already said, how comes this isn't a thing yet.


HTH,

M4
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On 10/6/21 10:48, Paul "LeoNerd" Evans wrote:
> On Thu, 10 Jun 2021 08:27:54 +0000
> Nicholas Clark <nick@ccl4.org> wrote:
>
>> 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.
>
> I've often pondered stealing Python's "enumerate" function; so that
> would be
>
>
> foreach my ($index, $item) (enumerate @array)
> {
> ...
> }
>
> Where `enumerate LIST` just yields (0, LIST[0], 1, LIST[1], ...)
>

This is probably going out of control but...

How about extending "for" with attributes?

for :enumerate my ($index, $item) (@a) { ... }

for :take(4) my (@b) (@a) { ... }

for my ($key, $val) (%hash) {
# implicit :take(2) ?
}

for :enumerate ($ix, $key, $val) (%hash) { ... }

for :enumerate :take(4) my ($ix, $foo, $bar) (@a) {
# note that 2 values are discarded
# in every iteration

}
Re: RFC: Multiple-alias syntax for for [ In reply to ]
Nicholas Clark <nick@ccl4.org> wrote:
: ## 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.

I'd like to add a vote for this to move from "rejected" to something
like "possible future extension", to capture the notion that "if we were
to support semantics like this, this is the syntax we'd want to use,
but we don't plan to support this for the first draft of the feature".

More generally, I think we should be slow to use "rejected" in this
context: as part of the record of an RFC process, that at least
somewhat implies "rejected for ever" - we're never going to want this
in the language. Certainly it sounds stronger than "I've chosen not
to put that in the first implementation".

(I do appreciate that all the information is there in the detail.
I just worry that labels tend to be sticky.)

The additional implication is that we should have tests in the first
implementation to assert that the extended syntax remains a syntax
error.

Hugo
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, 10 Jun 2021 14:04:59 +0200
Salvador Fandiño <sfandino@gmail.com> wrote:

> This is probably going out of control but...
>
> How about extending "for" with attributes?

I have often wanted that sort of thing (I call them "adverbs") in a
huge number of other places in perl. Far too many cases to list all of
them, but a couple of notable ones:

$str =~ s:nth(2)/foo/bar/; # substitute just the 2nd match

my @result = await map :concurrent(4) { afunc($_) } @items;

Such a thing could be an interesting idea, but it's a huge interesting
idea that involves lots of staring at lots of places, to see where and
how it might make sense.

First problem is that the syntax is too ambiguous:

map:concurrent(4)

is a call to the function &concurrent, taking the params (4), and the
statement happens to have a label `map:`. That colon notation gets in
the way alllll the time.

Annoyingly, I can't think of a good solution that doesn't start to
become whitespace-dependent; i.e. that

map: concurrent(4)

map :concurrent(4)

would need to have different meanings. And everyone is going to shoot
me for that idea.

--
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 Thu, Jun 10, 2021 at 9:27 AM <hv@crypt.org> wrote:

> Nicholas Clark <nick@ccl4.org> wrote:
> : ## 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.
>
> I'd like to add a vote for this to move from "rejected" to something
> like "possible future extension", to capture the notion that "if we were
> to support semantics like this, this is the syntax we'd want to use,
> but we don't plan to support this for the first draft of the feature".
>
> More generally, I think we should be slow to use "rejected" in this
> context: as part of the record of an RFC process, that at least
> somewhat implies "rejected for ever" - we're never going to want this
> in the language. Certainly it sounds stronger than "I've chosen not
> to put that in the first implementation".
>
> (I do appreciate that all the information is there in the detail.
> I just worry that labels tend to be sticky.)
>
> The additional implication is that we should have tests in the first
> implementation to assert that the extended syntax remains a syntax
> error.
>

Agreed, if it is an error now, it is trivial (design wise, at least) to add
support for it later.

-Dan
Re: RFC: Multiple-alias syntax for for [ In reply to ]
> I have often wanted that sort of thing (I call them "adverbs") in a
>
> First problem is that the syntax is too ambiguous:
>
>
Syntax issues avoided on "block API" concept with "alter meta operator"

Example of multi item traversal:

for (@list) {
has $item;
...
}

for (@list) {
has $item1;
has $item2;
...
}

for (@list) {
has $item1;
has $index1 := :is => Array::index;
has $item2 := :is => Array::next;
...
}

More at
https://github.com/happy-barney/perl-poc/blob/perl-features/COP/tests/traverse-multiple-items.t

Whole concept:
https://github.com/happy-barney/perl-poc/tree/perl-features/COP

Alter meta operator - preparing standalone RFC.
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, Jun 10, 2021 at 01:54:22PM +0100, hv@crypt.org wrote:
> Nicholas Clark <nick@ccl4.org> wrote:
> : ## Rejected Ideas
> :
> :+### Permit `undef` in the list of scalars

> I'd like to add a vote for this to move from "rejected" to something
> like "possible future extension", to capture the notion that "if we were
> to support semantics like this, this is the syntax we'd want to use,
> but we don't plan to support this for the first draft of the feature".

Yes, you're right. I failed to figure this out for myself when writing that
this particular decision was "subjective" and that I might be wrong on it.

It's not the same as the other things listed below it, which (likely) we
don't want to revisit.

Paul has also reached the same conclusion thinking about try/catch as an
RFC. So it's now in a section "Future Scope"

> More generally, I think we should be slow to use "rejected" in this
> context: as part of the record of an RFC process, that at least
> somewhat implies "rejected for ever" - we're never going to want this
> in the language. Certainly it sounds stronger than "I've chosen not
> to put that in the first implementation".
>
> (I do appreciate that all the information is there in the detail.
> I just worry that labels tend to be sticky.)

Yes. Does splitting things between "Future Scope" and "Rejected Ideas"
cover this? Or do need different names for "NO WAI!!" and "Out of Scope"?

> The additional implication is that we should have tests in the first
> implementation to assert that the extended syntax remains a syntax
> error.

That's a really good point, here and generally. Thanks.

(I'd missed this line in my first skim of your message. I'm going to update
the template to suggest this.)

Nicholas Clark
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, Jun 10, 2021 at 03:08:56PM +0100, Paul "LeoNerd" Evans wrote:
> On Thu, 10 Jun 2021 14:04:59 +0200
> Salvador Fandi?o <sfandino@gmail.com> wrote:
>
> > This is probably going out of control but...
> >
> > How about extending "for" with attributes?
>
> I have often wanted that sort of thing (I call them "adverbs") in a
> huge number of other places in perl. Far too many cases to list all of
> them, but a couple of notable ones:
>
> $str =~ s:nth(2)/foo/bar/; # substitute just the 2nd match

That's also already valid syntax (well, ish):

$ perl -e '$str =~ s:nth(2)/foo/bar/;'
Substitution pattern not terminated at -e line 1.

because it's s/// but with ':' instead of '/'

Larry's 2nd Law of Language Redesign: Larry gets the colon.

I don't actually know what the 1st Law as.

However, I do know the rough backstory, and the relevant detail...

IIRC the rough backstory was that during the RFC process (and later)
*everyone* was proposing different syntax using a colon. Most of which
was mutually exclusive (ie any one person's plan blocked 6+ others...)

So Larry wanted to be clear that he got to pick the syntax that used the
colon, to get maximum value by solving as many important problems as
possible.



But, the relevant detail here is:

$perl5 ? $ternary : $operator;

$perl6 ?? $ternary !! $operator;

(spelled appropriately for the context)


For Perl, the ternary operator rules out a lot of uses of the colon because
in any expression, likely a ':' will need to be parseable as part of a
ternary.


> First problem is that the syntax is too ambiguous:
>
> map:concurrent(4)
>
> is a call to the function &concurrent, taking the params (4), and the
> statement happens to have a label `map:`. That colon notation gets in
> the way alllll the time.
>
> Annoyingly, I can't think of a good solution that doesn't start to
> become whitespace-dependent; i.e. that
>
> map: concurrent(4)
>
> map :concurrent(4)
>
> would need to have different meanings. And everyone is going to shoot
> me for that idea.

It seems calmer to run the thought experiment "What would Abigail think?"


I'd forgotten about labels. So, so far, "things that like the colon"

1) ternaries
2) labels
3) delimiters for q-like operators


Likewise, '.' works as a method call operator because concatenation became
'~', (and bitwise '~' is pushed onward...)

But the subtle part is that you also need matching became '~~'.

Without that change, you have '.=' morphing to '~=', but '=~' would still be
legal, so confusing legal syntax typos abound...


And this is part of the "Perl should stay Perl" conundrum.

1) How far can you bend syntax whilst still being understandable?
2) What existing other syntax is "getting in the way" of your good idea.


A lot of the stuff in the language-formerly-known-as-Perl-6 only works as
part of a *grand* redesign. It's difficult to cherry-pick out parts that
are unambiguously "useful to us" and "a good solution" because often they
depend on other things being changed to work well, if at all.

So adverbs starting `:` is one of these things - I think most of us think
that this is nice, obvious syntax, and we'd love to have it.

*but*

where we can use it is limited by at least 3 existing other uses of ':',
and it's not clear

1) how far that restricts it
2) whether attempting to remove those restrictions costs more than benefits

(and as ever, these are design trade offs, so different people value them
differently, and that's quite legitimate. Which just adds to the fun.)


Nicholas Clark
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, 10 Jun 2021 07:28:16 +0000
Nicholas Clark <nick@ccl4.org> wrote:

> 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)

I'd agree with that. That's also consistent with how my newly-added
List::Util::zip and ::mesh functions work; documented thus:

>> ... If any input arrays run out of elements before others, then
>> "undef" will be inserted into the result to fill in the gaps.

--
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 Fri, Jun 11, 2021 at 10:38:43AM +0100, Paul "LeoNerd" Evans wrote:
> On Thu, 10 Jun 2021 07:28:16 +0000
> Nicholas Clark <nick@ccl4.org> wrote:
>
> > 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)
>
> I'd agree with that. That's also consistent with how my newly-added
> List::Util::zip and ::mesh functions work; documented thus:

Good, and thanks for the confirmation that it wasn't a totally daft idea.

PEP1 has:

Finally, a proposed enhancement must be "pythonic" in order to be
accepted by the Steering Council. (However, "pythonic" is an imprecise
term; it may be defined as whatever is acceptable to the Steering
Council. This logic is intentionally circular.)


I'm guessing that we want things to be "perlish". Tentatively that seems
to be some blend of

* shown just the code, a perl programmer would guess behaviour consistent
with the documentation you actually wrote
* looks like it was always part of the language
* behaves consistently with existing similar features - easy to teach


Of course, when you start with a language with

less a design than a thousand special features flying in close formation

(I can't find the an attribution on that one)

then some of that existing behaviour is undoubtedly something that with
hindsight should have been done differently. So staying consistent with it
is repeating mistakes. You can't always win.


Nicholas Clark
Re: RFC: Multiple-alias syntax for for [ In reply to ]
Nicholas Clark <nick@ccl4.org> wrote:
:On Thu, Jun 10, 2021 at 01:54:22PM +0100, hv@crypt.org wrote:
:> More generally, I think we should be slow to use "rejected" in this
:> context: as part of the record of an RFC process, that at least
:> somewhat implies "rejected for ever" - we're never going to want this
:> in the language. Certainly it sounds stronger than "I've chosen not
:> to put that in the first implementation".
:
:Yes. Does splitting things between "Future Scope" and "Rejected Ideas"
:cover this? Or do need different names for "NO WAI!!" and "Out of Scope"?

I think the former is fine; the process documentation should try to make
clear how complete or permanent the rejection is.

Hugo
Re: RFC: Multiple-alias syntax for for [ In reply to ]
Rule 2 violation!

On Fri, Jun 11, 2021 at 7:32 AM <hv@crypt.org> wrote:

> Nicholas Clark <nick@ccl4.org> wrote:
> :On Thu, Jun 10, 2021 at 01:54:22PM +0100, hv@crypt.org wrote:
> :>

--
"Lay off that whiskey, and let that cocaine be!" -- Johnny Cash
Re: RFC: Multiple-alias syntax for for [ In reply to ]
Your entire message arrives as:

On Fri, Jun 11, 2021 at 09:52:59AM -0500, David Nicol wrote:
> Rule 2 violation!
>
> On Fri, Jun 11, 2021 at 7:32 AM <hv@crypt.org> wrote:
>
> > Nicholas Clark <nick@ccl4.org> wrote:
> > :On Thu, Jun 10, 2021 at 01:54:22PM +0100, hv@crypt.org wrote:
> > :>
>
> --
> "Lay off that whiskey, and let that cocaine be!" -- Johnny Cash

You don't actually quote enough for the comment to make sense to me.
I'm guessing

Rule 1: Larry is always right
Rule 2: Larry is allowed to change his mind


and a rule 2 violation would be a concept of "permanent rejection" given
that that *appears* to preclude changing one's mind.

If so, I'm not convinced that it is, because Larry (or the successor to
the BDFL, the Benevolent elected For a-term-at-a-time (in triplicate))
would change his mind (its hive-mind) when presented with new evidence,
or if re-evaluating something and discovering a mistake.

In the absence of new evidence, a competent BDFL (or hive mind) will
have feel for how confident it is that the existing decision is correct
based on the currently available evidence.


Or did I guess wrong and this is about something else?

eg - it was a *Law* of Language Redesign that Larry got the colon.
(Law 1, I found soon after mailing) was "Everyone wants the colon"
and Hugo's mailer is quoting with colons

If so, I guess this confusion is rather like:

Sturgeon's Law: "nothing is always absolutely so"
Sturgeon's Revelation: "ninety percent of everything is crap"


Nicholas Clark
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Thu, Jun 10, 2021 at 04:24:42AM -0400, Dan Book wrote:
> 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.

It turns out that this is how the docs do it. (More below)

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

I think this too, but I realise that one of us might spot a good way to do
it that doesn't have much extra complication. In particular, I suspect that
if it's possible to set the Pad up the same way that anonymous entries such
as TARG slots are represented, then there might be zero runtime overhead
for "aliasing" to "undef".



So, anyway, I think that we've got to this stage:

|
v
Provisional RFC
"we think this idea is worth implementing"
(We have a firm idea of what we want to do)



There are 4 open issues that I can see, that I'm not sure about:

1) Should this be behind a feature guard?
2) Should it issue an experimental warning?
3) Are there any examples that aren't already in the *Motivation* section?
4) Are there any *Security Implications*?


Right now my test implementation doesn't guard or warn:

https://github.com/nwc10/perl5/commits/smoke-me/nicholas/pp_iter

but I think if either are needed, the "right" place is in `yyl_foreach`

I filled out the "Specification" and "Backwards Compatibility" sections.

I like the idea of the "Specification" just *being* the proposed end-user
documentation, but I'm not sure if a diff-hunk is the best way to express
this. I used one because it seemed the easiest way to say "I need to change
the Pod file in these three places, in this way". So diff and context :-)

Nicholas Clark


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

## Specification

```
diff --git a/pod/perlsyn.pod b/pod/perlsyn.pod
index fe511f052e..490119d00e 100644
--- a/pod/perlsyn.pod
+++ b/pod/perlsyn.pod
@@ -282,6 +282,14 @@ The following compound statements may be used to control flow:

PHASE BLOCK

+As of Perl 5.36, you can iterate over multiple values at a time by specifying
+a list of lexicals within parentheses
+
+ LABEL for my (VAR, VAR) (LIST) BLOCK
+ LABEL for my (VAR, VAR) (LIST) BLOCK continue BLOCK
+ LABEL foreach my (VAR, VAR) (LIST) BLOCK
+ LABEL foreach my (VAR, VAR) (LIST) BLOCK continue BLOCK
+
If enabled by the experimental C<try> feature, the following may also be used

try BLOCK catch (VAR) BLOCK
@@ -549,6 +557,14 @@ followed by C<my>. To use this form, you must enable the C<refaliasing>
feature via C<use feature>. (See L<feature>. See also L<perlref/Assigning
to References>.)

+As of Perl 5.36, you can iterate over a list of lexical scalars n-at-a-time.
+If the size of the LIST is not an exact multiple of number of iterator
+variables, then on the last iteration the "excess" iterator variables are
+undefined values, much like if you slice beyond the end of an array. You
+can only iterate over scalars - unlike list assignment, it's not possible to
+use C<undef> to signify a value that isn't wanted. This is a limitation of
+the current implementation, and might be changed in the future.
+
Examples:

for (@ary) { s/foo/bar/ }
@@ -574,6 +590,17 @@ Examples:
# do something which each %hash
}

+ foreach my ($foo, $bar, $baz) (@list) {
+ # do something three-at-a-time
+ }
+
+ foreach my ($key, $value) (%hash) {
+ # iterate over the hash
+ # The hash is eagerly flattened to a list before the loop starts,
+ # but as ever keys are copies, values are aliases.
+ # This is the same behaviour as for $var (%hash) {...}
+ }
+
Here's how a C programmer might code up a particular algorithm in Perl:

for (my $i = 0; $i < @ary1; $i++) {
```

## Backwards Compatibility

The new syntax is a syntax error on existing Perls. It generates this error message

`Missing $ on loop variable at /home/nick/test/three-at-a-time.pl line 4.`

Existing static tooling should be able to recognise it as a syntax error, but without changes wouldn't be able to give any better diagnostics.

The proposed implementation has tests and patches for `B::Deparse` and `B::Concise`. `Devel::Cover`, `Devel::NYTProf` and `Perl::Critic` handle the new syntax just fine.

I don't think that we have any way to emulate this syntax for earlier Perls. I don't have any feel for what sort of API we would need to add to the parser to make it possible in the future, and whether any API we could add would be fragile and tightly coupled to the exact current implementation.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Mon, Jun 14, 2021 at 4:22 AM Nicholas Clark <nick@ccl4.org> wrote:

>
> I don't think that we have any way to emulate this syntax for earlier
> Perls. I don't have any feel for what sort of API we would need to add to
> the parser to make it possible in the future, and whether any API we could
> add would be fragile and tightly coupled to the exact current
> implementation.
>


this, like most all syntax extension proposals, could be done with a robust
macro system which would hook the "for" keyword and own the parser for a
few tokens. As to aliases instead of copies, it seems it would rely on
lexical aliasing unless the macro system was outputting to a deeper level
than a miniperl.



--
"Lay off that whiskey, and let that cocaine be!" -- Johnny Cash
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Mon, Jun 14, 2021 at 08:51:20AM -0500, David Nicol wrote:
> On Mon, Jun 14, 2021 at 4:22 AM Nicholas Clark <nick@ccl4.org> wrote:
>
> >
> > I don't think that we have any way to emulate this syntax for earlier
> > Perls. I don't have any feel for what sort of API we would need to add to
> > the parser to make it possible in the future, and whether any API we could
> > add would be fragile and tightly coupled to the exact current
> > implementation.
> >
>
>
> this, like most all syntax extension proposals, could be done with a robust
> macro system which would hook the "for" keyword and own the parser for a
> few tokens.

I appreciate that you're trying to make helpful suggestions, but that level
of detail is "obviously true" without giving any idea about how to implement
it. For getting to a working solution, it's about as useful as jokingly
observing that "any sufficiently advanced technology is indistinguishable
from magic". (Which, sometimes, is what the perl internals feel like.)

"macro system" - yes, sure, what one seems to need is a way to be able to
tag each keyword with "actually, don't use the regular parser here, call
me instead". So with that in place, when the parser gets to a keyword and
it's `for` it takes the "have a macro override path"

But what's down that path? Really, if we do that, we need to have a
*complete* *re-implementation* of the parsing of `for` (all the way to the
end of any `continue` block), so that we can then make arbitrary other
changes (eg, add an optional `else` block to `for` blocks).

Which means that we need a complete and correct parser. For that version of
perl. For *each* and *every* version of perl that we want to "polyfill"
back to. Because Perl C parser code changes between each release. Which
means

1) either our CPAN module has to ship copies of each and every parser
2) or we actually then have to re-write the parser so that it itself is
implemented as a macro system internally. So our "new syntax" module can
just change the macros.


Either way would be hard. Rewriting the parser - well, the lexer code is C
code. The grammar *is* a grammar, sure, but it's *compiled* to fixed C
data structures by bison, and we put *that* C into git. And that C is
compiled to fixed data structures at build time. We couldn't change Perl's
parser to be "runtime malleable" with macros (in any generic way) without
completely rewriting it *not* to use bison.


And *that* level of detail for a thought experiment might be useful. But
that's not what you wrote. And hence why it's actually not that helpful
to suggest generic broad concept ideas, particularly when the folks who
say that they are stuck have a heck of a lot more experience of the evil
horrors of the internals than you do. (You are lucky. You have no scars.)

> As to aliases instead of copies, it seems it would rely on
> lexical aliasing unless the macro system was outputting to a deeper level
> than a miniperl.

That's really actually not a problem. The C internals throw pointers to SVs
around. Aliasing and binding are trivial at the C level.

Different runtime behaviour is easy (enough) with custom OPs.

It's not really the way that you assumed that it was. The problem is really
the parser, not the runtime.

Nicholas Clark
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Mon, Jun 14, 2021 at 5:23 AM Nicholas Clark <nick@ccl4.org> wrote:

> There are 4 open issues that I can see, that I'm not sure about:
>
> 1) Should this be behind a feature guard?
>

Since the current proposed syntax has no conflicts, I don't think this is
needed.


> 2) Should it issue an experimental warning?
>

This might be prudent, regardless.

-Dan
Re: RFC: Multiple-alias syntax for for [ In reply to ]
2021-6-14 18:23 Nicholas Clark <nick@ccl4.org> wrote

>
>
> So, anyway, I think that we've got to this stage:
>
> |
> v
> Provisional RFC
> "we think this idea is worth implementing"
> (We have a firm idea of what we want to do)
>
>
I think it's good.


>
> 4) Are there any *Security Implications*?
>
>
Personally, I think this syntax doesn't affect security.
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Mon, Jun 14, 2021 at 09:22:10AM +0000, Nicholas Clark wrote:
> 2) Should it issue an experimental warning?

I think it should at least have an experimental warning, mostly as a
"coders haven't beating on the implementation for N years, there might
be bugs" warning.

Chained comparisons didn't get such a warning, and that had one
serious bug that I'm aware of (constant folding could underflow the
stack.)

Tony
Re: RFC: Multiple-alias syntax for for [ In reply to ]
On Mon, 14 Jun 2021 at 17:28, Dan Book <grinnz@gmail.com> wrote:

> On Mon, Jun 14, 2021 at 5:23 AM Nicholas Clark <nick@ccl4.org> wrote:
>
>> There are 4 open issues that I can see, that I'm not sure about:
>>
>> 1) Should this be behind a feature guard?
>>
>
> Since the current proposed syntax has no conflicts, I don't think this is
> needed.
>

Wrong

It has conflicts, with every perl before one implementing it.
Therefore it should required at least bundle specification


>
>
>> 2) Should it issue an experimental warning?
>>
>
> This might be prudent, regardless.
>
> -Dan
>

1 2 3  View All