Mailing List Archive

Pre elevator pitch: Loop Info
Hello All,

I would like to get opinions from the community on a change I would like to see, so I thought I write my PrePPC in the style as defined on https://github.com/Perl/PPCs

So keeping it short and sweet, here is my thinking:

Here is a problem.
I cannot without adding additional code find out what positing in an index I am presently processing, nor can I tell if I am on the final iteration.

Here is the syntax that I’m proposing.
${^LOOPCOUNT} and ${^LOOPINDEX} (Naming is not final, willing to change if people would prefer something else}, available in every FOR & FOREACH.

Here are the benefits of this.
No more $i’s everywhere being untidy.
Removing the constant questions regarding this very functionality that seem to have happened frequently since the birth of Perl.

Here are the potential problems.
Minor overhead added to all loops, though perhaps this could be a triggerable feature requiring a “use feature ‘infoloop’” or such.

Thank you for reading ????
Re: Pre elevator pitch: Loop Info [ In reply to ]
On Sun, 7 Jan 2024 16:16:38 -0000
"Paul Webster" via perl5-porters <perl5-porters@perl.org> wrote:

> Here is the syntax that I’m proposing.
> ${^LOOPCOUNT} and ${^LOOPINDEX} (Naming is not final, willing
> to change if people would prefer something else}, available in every
> FOR & FOREACH.

(Having originally handwaved a suggestion on IRC for this) - I imagined
somewhat shorter names, maybe ${^INDEX} and ${^COUNT}

An idea for a usecase could be

foreach my $row (@rows) {
say "<table>" if ${^INDEX} == 0;
say "<tr>" . $row->as_html . "</tr>";
say "</table>" if ${^INDEX} == ${^COUNT}-1;
}

This way, if there are no rows we don't print an empty table container.
It's a bit shorter than the alternative

if(@rows) {
say "<table>";
foreach my $row (@rows) { ... }
say "</table>";
}

> Here are the potential problems.
> Minor overhead added to all loops, though perhaps this could
> be a triggerable feature requiring a “use feature ‘infoloop’” or such.

I was thinking about this too. I think if you said they had dynamic
scope, then it would indeed add a performance hit everywhere.

*But* if they are lexically scoped, only taking effect inside a lexical
foreach loop, then at compiletime we know which loops need them and can
account for them. It means the cost isn't paid anywhere else.


But overall - yes I would like to see a PPC document on this at least
so we can discuss it in further detail.

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: Pre elevator pitch: Loop Info [ In reply to ]
re naming: LOOP_COUNT / LOOP_INDEX

questions:
- performance how often these variants are needed? what will be performance
impact?
- will these variables will be visible outside of loop (eg: called
functions)?
- how nested loops will be treated? (stack of loops?)
- how it will interact with redo?
- how it will interact will multivalue iterations ?
- how it will interact with "goto into loop"
- consistency: should be available for while / until as well

consider usage of attributes (introducing new attribute context), eg:
for := loop_info my $key (keys %hash) {
}

Brano

On Sun, 7 Jan 2024 at 17:16, Paul Webster via perl5-porters <
perl5-porters@perl.org> wrote:

> Hello All,
>
> I would like to get opinions from the community on a change I would like
> to see, so I thought I write my PrePPC in the style as defined on
> https://github.com/Perl/PPCs
>
> So keeping it short and sweet, here is my thinking:
>
> Here is a problem.
> I cannot without adding additional code find out what positing in
> an index I am presently processing, nor can I tell if I am on the final
> iteration.
>
> Here is the syntax that I’m proposing.
> ${^LOOPCOUNT} and ${^LOOPINDEX} (Naming is not final, willing to
> change if people would prefer something else}, available in every FOR &
> FOREACH.
>
> Here are the benefits of this.
> No more $i’s everywhere being untidy.
> Removing the constant questions regarding this very functionality
> that seem to have happened frequently since the birth of Perl.
>
> Here are the potential problems.
> Minor overhead added to all loops, though perhaps this could be a
> triggerable feature requiring a “use feature ‘infoloop’” or such.
>
> Thank you for reading ????
>
>
>
Re: Pre elevator pitch: Loop Info [ In reply to ]
On Sun, 7 Jan 2024 18:02:31 +0000
"Paul \"LeoNerd\" Evans" <leonerd@leonerd.org.uk> wrote:

> foreach my $row (@rows) {
> say "<table>" if ${^INDEX} == 0;
> say "<tr>" . $row->as_html . "</tr>";
> say "</table>" if ${^INDEX} == ${^COUNT}-1;
> }

This works today:

use builtin 'indexed';

for my($i, $row) (indexed @rows) {
say "<table>" if $i == 0;
say "<tr>" . $row->as_html . "</tr>";
say "</table>" if $i == $#rows;
}
RE: Pre elevator pitch: Loop Info [ In reply to ]
Good day Branislav,



In regard to your questions, a couple of them I can’t answer this moment will have to have a think:



Names counter:

1 Branislav Zahradník LOOP_COUNT / LOOP_INDEX

1 Paul Webster COUNT / INDEX



questions:

- performance how often these variants are needed? what will be performance impact?

-- This would be very difficult to determine without testing, but I was hoping for the inclusion of requiring ‘use feature “infoloops”’ or something akin would be the perfect opportunity to allow high performance code to not be affected by this change.

-- I would of course also not expect a huge impact for such a simple feature!



- will these variables will be visible outside of loop (eg: called functions)?

-- No



- how nested loops will be treated? (stack of loops?)

-- Each scope will have its counter



- how it will interact with redo?

-- leave this one with me ????



- how it will interact will multivalue iterations ?

-- Each value would have its own index and count



- how it will interact with "goto into loop"

-- Leave this one with me ????



- consistency: should be available for while / until as well

-- No, the values of a while is known upfront already





From: Branislav Zahradník <happy.barney@gmail.com>
Sent: Sunday, January 7, 2024 6:09 PM
To: paul.g.webster@googlemail.com
Cc: perl5-porters@perl.org
Subject: Re: Pre elevator pitch: Loop Info



re naming: LOOP_COUNT / LOOP_INDEX



questions:

- performance how often these variants are needed? what will be performance impact?

- will these variables will be visible outside of loop (eg: called functions)?

- how nested loops will be treated? (stack of loops?)

- how it will interact with redo?

- how it will interact will multivalue iterations ?

- how it will interact with "goto into loop"

- consistency: should be available for while / until as well



consider usage of attributes (introducing new attribute context), eg:

for := loop_info my $key (keys %hash) {

}



Brano



On Sun, 7 Jan 2024 at 17:16, Paul Webster via perl5-porters <perl5-porters@perl.org <mailto:perl5-porters@perl.org> > wrote:

Hello All,

I would like to get opinions from the community on a change I would like to see, so I thought I write my PrePPC in the style as defined on https://github.com/Perl/PPCs

So keeping it short and sweet, here is my thinking:

Here is a problem.
I cannot without adding additional code find out what positing in an index I am presently processing, nor can I tell if I am on the final iteration.

Here is the syntax that I’m proposing.
${^LOOPCOUNT} and ${^LOOPINDEX} (Naming is not final, willing to change if people would prefer something else}, available in every FOR & FOREACH.

Here are the benefits of this.
No more $i’s everywhere being untidy.
Removing the constant questions regarding this very functionality that seem to have happened frequently since the birth of Perl.

Here are the potential problems.
Minor overhead added to all loops, though perhaps this could be a triggerable feature requiring a “use feature ‘infoloop’” or such.

Thank you for reading ????
Re: Pre elevator pitch: Loop Info [ In reply to ]
On Sun, 7 Jan 2024 at 19:36, Paul Webster <paul.g.webster@googlemail.com>
wrote:

> Good day Branislav,
>
>
>
> In regard to your questions, a couple of them I can’t answer this moment
> will have to have a think:
>
>
>
> Names counter:
>
> 1 Branislav Zahradník LOOP_COUNT / LOOP_INDEX
>
> 1 Paul Webster COUNT / INDEX
>
>
>
> questions:
>
> - performance how often these variants are needed? what will be
> performance impact?
>
> -- This would be very difficult to determine without testing, but I was
> hoping for the inclusion of requiring ‘use feature “infoloops”’ or
> something akin would be the perfect opportunity to allow high performance
> code to not be affected by this change.
>
> -- I would of course also not expect a huge impact for such a simple
> feature!
>
>
>
> - will these variables will be visible outside of loop (eg: called
> functions)?
>
> -- No
>

ie no usage in logs


>
>
> - how nested loops will be treated? (stack of loops?)
>
> -- Each scope will have its counter
>

let me explain it little bit more:
- will these variables be visible (somehow, eg @{ ^LOOP_COUNT} [1]) in
nested loop?


>
>
> - how it will interact with redo?
>
> -- leave this one with me ????
>
>
>
> - how it will interact will multivalue iterations ?
>
> -- Each value would have its own index and count
>

for my ($x, $y) (1 .. 4) {
say "${^COUNT} - ${^INDEX} - $x - $y";
}

what will be output of this?


>
> - how it will interact with "goto into loop"
>
> -- Leave this one with me ????
>
>
>
> - consistency: should be available for while / until as well
>
> -- No, the values of a while is known upfront already
>

that's quite an inconsistency


reflecting `builtin::indexed` mentioned elsewhere - maybe another builtin
interacting with loop?

for my ($count, $index1, $value1, $index2, $value2) ( counted indexed
@array) {
}

this will solve your problem, will not have unnecessary performance impact,
and will maintain
visibility in nested loops.


>
> *From:* Branislav Zahradník <happy.barney@gmail.com>
> *Sent:* Sunday, January 7, 2024 6:09 PM
> *To:* paul.g.webster@googlemail.com
> *Cc:* perl5-porters@perl.org
> *Subject:* Re: Pre elevator pitch: Loop Info
>
>
>
> re naming: LOOP_COUNT / LOOP_INDEX
>
>
>
> questions:
>
> - performance how often these variants are needed? what will be
> performance impact?
>
> - will these variables will be visible outside of loop (eg: called
> functions)?
>
> - how nested loops will be treated? (stack of loops?)
>
> - how it will interact with redo?
>
> - how it will interact will multivalue iterations ?
>
> - how it will interact with "goto into loop"
>
> - consistency: should be available for while / until as well
>
>
>
> consider usage of attributes (introducing new attribute context), eg:
>
> for := loop_info my $key (keys %hash) {
>
> }
>
>
>
> Brano
>
>
>
> On Sun, 7 Jan 2024 at 17:16, Paul Webster via perl5-porters <
> perl5-porters@perl.org> wrote:
>
> Hello All,
>
> I would like to get opinions from the community on a change I would like
> to see, so I thought I write my PrePPC in the style as defined on
> https://github.com/Perl/PPCs
>
> So keeping it short and sweet, here is my thinking:
>
> Here is a problem.
> I cannot without adding additional code find out what positing in
> an index I am presently processing, nor can I tell if I am on the final
> iteration.
>
> Here is the syntax that I’m proposing.
> ${^LOOPCOUNT} and ${^LOOPINDEX} (Naming is not final, willing to
> change if people would prefer something else}, available in every FOR &
> FOREACH.
>
> Here are the benefits of this.
> No more $i’s everywhere being untidy.
> Removing the constant questions regarding this very functionality
> that seem to have happened frequently since the birth of Perl.
>
> Here are the potential problems.
> Minor overhead added to all loops, though perhaps this could be a
> triggerable feature requiring a “use feature ‘infoloop’” or such.
>
> Thank you for reading ????
>
>
Re: Pre elevator pitch: Loop Info [ In reply to ]
On 2024-01-07 10:17 a.m., Tomasz Konojacki wrote:
> This works today:
>
> use builtin 'indexed';
>
> for my($i, $row) (indexed @rows) {
> say "<table>" if $i == 0;
> say "<tr>" . $row->as_html . "</tr>";
> say "</table>" if $i == $#rows;
> }

As far as knowing what the current index is in a foreach loop, I feel that
explicit loop variable declarations such as shown here is by far the best
approach, and as we see it is already implemented. I don't feel that adding
special implicit variables like the original proposal is an improvement, and per
other responses seem to have a lot of downsides. The problem is already solved
it seems. -- Darren Duncan
Re: Pre elevator pitch: Loop Info [ In reply to ]
On Sun, 7 Jan 2024 at 18:02, Paul "LeoNerd" Evans
<leonerd@leonerd.org.uk> wrote:

> An idea for a usecase could be
>
> foreach my $row (@rows) {
> say "<table>" if ${^INDEX} == 0;
> say "<tr>" . $row->as_html . "</tr>";
> say "</table>" if ${^INDEX} == ${^COUNT}-1;
> }

As a bit of prior art, the Template Toolkit gives you access to a
"loop" variable inside all loops. I particularly like the loop.first
and loop.last boolean flags it contains that would make the above code
even more readable.

foreach my $row (@rows) {
say "<table>" if ${^LOOPFIRST};
say "<tr>" . $row->as_html . "</tr>";
say "</table>" if ${^INDEX} == ${LOOPLAST};
}

https://metacpan.org/dist/Template-Toolkit/view/lib/Template/Manual/Variables.pod#loop
https://metacpan.org/pod/Template::Iterator

Dave...
Re: Pre elevator pitch: Loop Info [ In reply to ]
I feel that a better example use case would be when ALTERING the behavior for
dealing with the first or last loop element itself, such as by producing the
first or last table row itself in a different way. I feel this example is weak
since arguably a better design would be having the framing "table" entirely
outside of the loop logic, before/after it. If there is a good reason to prefer
putting those "table" lines inside the foreach loop instead, I'd like to know
what it is. -- Darren Duncan

On 2024-01-08 2:07 a.m., Dave Cross wrote:
> On Sun, 7 Jan 2024 at 18:02, Paul "LeoNerd" Evans wrote:
>
>> An idea for a usecase could be
>>
>> foreach my $row (@rows) {
>> say "<table>" if ${^INDEX} == 0;
>> say "<tr>" . $row->as_html . "</tr>";
>> say "</table>" if ${^INDEX} == ${^COUNT}-1;
>> }
>
> As a bit of prior art, the Template Toolkit gives you access to a
> "loop" variable inside all loops. I particularly like the loop.first
> and loop.last boolean flags it contains that would make the above code
> even more readable.
>
> foreach my $row (@rows) {
> say "<table>" if ${^LOOPFIRST};
> say "<tr>" . $row->as_html . "</tr>";
> say "</table>" if ${^INDEX} == ${LOOPLAST};
> }
>
> https://metacpan.org/dist/Template-Toolkit/view/lib/Template/Manual/Variables.pod#loop
> https://metacpan.org/pod/Template::Iterator
>
> Dave...
Re: Pre elevator pitch: Loop Info [ In reply to ]
On Mon, 8 Jan 2024 at 11:41, Darren Duncan <darren@darrenduncan.net> wrote:

> I feel that a better example use case would be when ALTERING the behavior
> for
> dealing with the first or last loop element itself, such as by producing
> the
> first or last table row itself in a different way. I feel this example is
> weak
> since arguably a better design would be having the framing "table"
> entirely
> outside of the loop logic, before/after it. If there is a good reason to
> prefer
> putting those "table" lines inside the foreach loop instead, I'd like to
> know
> what it is. -- Darren Duncan
>
> On 2024-01-08 2:07 a.m., Dave Cross wrote:
> > On Sun, 7 Jan 2024 at 18:02, Paul "LeoNerd" Evans wrote:
> >
> >> An idea for a usecase could be
> >>
> >> foreach my $row (@rows) {
> >> say "<table>" if ${^INDEX} == 0;
> >> say "<tr>" . $row->as_html . "</tr>";
> >> say "</table>" if ${^INDEX} == ${^COUNT}-1;
> >> }
>
>
hm, you made me think ... as far as we already have continue and finally
... what about:

for ... {
say qq (<tr>${ \ $row->as_html }</tr>);
}
initially {
say q (<table>);
}
finally {
say q (</table>);
}
Re: Pre elevator pitch: Loop Info [ In reply to ]
Paul "LeoNerd" Evans, 2024-01-07 18:02 +0000:
> An idea for a usecase could be
>
> foreach my $row (@rows) {
> say "<table>" if ${^INDEX} == 0;
> say "<tr>" . $row->as_html . "</tr>";
> say "</table>" if ${^INDEX} == ${^COUNT}-1;
> }

Another one, perhaps even more illustrative:

"<tr class=" . (${^COUNT} % 2 ? "odd" : "even") . ...

I personally gravitate more towards explicit $i for-loops,
but let's see a PPC.
RE: Pre elevator pitch: Loop Info [ In reply to ]
Other than preferring the slightly longer naming, it sounds like a perfect pitch!

And to be 100% honest even if it was ${^SUPER_LONG_MAGICAL_NAME} I would still be overjoyed to finally see this feature in perl.

So with that said, indeed; does everyone think this should happen and it should be moved to a real elevator pitch?

If so please send in a Yes or No and just for the curiosity what names you would like.

There is also the name for the feature itself: 'loopinfo' would be good to see what people thought to that as well (name wise) ????

-----Original Message-----
From: Paul "LeoNerd" Evans <leonerd@leonerd.org.uk>
Sent: Sunday, January 7, 2024 6:03 PM
To: Paul Webster" via perl5-porters <perl5-porters@perl.org>
Cc: paul.g.webster@googlemail.com
Subject: Re: Pre elevator pitch: Loop Info

On Sun, 7 Jan 2024 16:16:38 -0000
"Paul Webster" via perl5-porters <perl5-porters@perl.org> wrote:

> Here is the syntax that I’m proposing.
> ${^LOOPCOUNT} and ${^LOOPINDEX} (Naming is not final, willing to
> change if people would prefer something else}, available in every FOR
> & FOREACH.

(Having originally handwaved a suggestion on IRC for this) - I imagined somewhat shorter names, maybe ${^INDEX} and ${^COUNT}

An idea for a usecase could be

foreach my $row (@rows) {
say "<table>" if ${^INDEX} == 0;
say "<tr>" . $row->as_html . "</tr>";
say "</table>" if ${^INDEX} == ${^COUNT}-1;
}

This way, if there are no rows we don't print an empty table container.
It's a bit shorter than the alternative

if(@rows) {
say "<table>";
foreach my $row (@rows) { ... }
say "</table>";
}

> Here are the potential problems.
> Minor overhead added to all loops, though perhaps this could be a
> triggerable feature requiring a “use feature ‘infoloop’” or such.

I was thinking about this too. I think if you said they had dynamic scope, then it would indeed add a performance hit everywhere.

*But* if they are lexically scoped, only taking effect inside a lexical foreach loop, then at compiletime we know which loops need them and can account for them. It means the cost isn't paid anywhere else.


But overall - yes I would like to see a PPC document on this at least so we can discuss it in further detail.

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: Pre elevator pitch: Loop Info [ In reply to ]
First, an observation.

In a perl for loop you can't, in general, pre-determine the number of
iterations there will be, nor can you tell whether you are currently on
the last iteration. For example:

@a = (1,2,3);

for (@a) {
push @a, 4 if $_ == 3;
print "$_\n";
}

which outputs 1..4. You can have similar weirdness by shortening @a
mid-iteration. Furthermore, @a may be tied.

And now onto some opinions.

We absolutely should not use global special variables, i.e. $^{...}. If a
variable is needed, it should be lexical (possibly implicitly so) and be
declared as part of the 'for' syntax, e.g.

for my $x :$i (...) { ... }
or
for my ($x, $y) ->$i (...) { ... }

(those aren't firm proposals, just examples)

Anything which requires extra work will slow down iteration. At a minimum,
it will require an extra flag check per iteration to decide whether it can
skip the increment code.

--
Red sky at night - gerroff my land!
Red sky at morning - gerroff my land!
-- old farmers' sayings #14
Re: Pre elevator pitch: Loop Info [ In reply to ]
On Sun, Jan 7, 2024 at 5:16?PM Paul Webster via perl5-porters <
perl5-porters@perl.org> wrote:

> Hello All,
>
> I would like to get opinions from the community on a change I would like
> to see, so I thought I write my PrePPC in the style as defined on
> https://github.com/Perl/PPCs
>
> So keeping it short and sweet, here is my thinking:
>
> Here is a problem.
> I cannot without adding additional code find out what positing in
> an index I am presently processing, nor can I tell if I am on the final
> iteration.
>
> Here is the syntax that I’m proposing.
> ${^LOOPCOUNT} and ${^LOOPINDEX} (Naming is not final, willing to
> change if people would prefer something else}, available in every FOR &
> FOREACH.
>
> Here are the benefits of this.
> No more $i’s everywhere being untidy.
> Removing the constant questions regarding this very functionality
> that seem to have happened frequently since the birth of Perl.
>
> Here are the potential problems.
> Minor overhead added to all loops, though perhaps this could be a
> triggerable feature requiring a “use feature ‘infoloop’” or such.
>
> Thank you for reading ????
>

I really hate the idea of using a magical variable for this for many
reasons, its unnestability being the most obvious one.

Clearly, functionality similar to ${^LOOPINDEX} should be possible by using
a multivar for loop and a helper function. E.g.

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

That doesn't actually require any extension of the language (though
multivar for is still experimental).

Leon
Re: Pre elevator pitch: Loop Info [ In reply to ]
On Tue, Jan 9, 2024 at 6:47?PM Leon Timmermans <fawaka@gmail.com> wrote:

> On Sun, Jan 7, 2024 at 5:16?PM Paul Webster via perl5-porters <
> perl5-porters@perl.org> wrote:
>
>> Hello All,
>>
>> I would like to get opinions from the community on a change I would like
>> to see, so I thought I write my PrePPC in the style as defined on
>> https://github.com/Perl/PPCs
>>
>> So keeping it short and sweet, here is my thinking:
>>
>> Here is a problem.
>> I cannot without adding additional code find out what positing in
>> an index I am presently processing, nor can I tell if I am on the final
>> iteration.
>>
>> Here is the syntax that I’m proposing.
>> ${^LOOPCOUNT} and ${^LOOPINDEX} (Naming is not final, willing to
>> change if people would prefer something else}, available in every FOR &
>> FOREACH.
>>
>> Here are the benefits of this.
>> No more $i’s everywhere being untidy.
>> Removing the constant questions regarding this very functionality
>> that seem to have happened frequently since the birth of Perl.
>>
>> Here are the potential problems.
>> Minor overhead added to all loops, though perhaps this could be a
>> triggerable feature requiring a “use feature ‘infoloop’” or such.
>>
>> Thank you for reading ????
>>
>
> I really hate the idea of using a magical variable for this for many
> reasons, its unnestability being the most obvious one.
>
> Clearly, functionality similar to ${^LOOPINDEX} should be possible by
> using a multivar for loop and a helper function. E.g.
>
> for my ($index,$value) (kv(@values)) { ... }
>
> That doesn't actually require any extension of the language (though
> multivar for is still experimental).
>

Sorry to go on even more of a tangent but this gave me a thought about
previously proposed iterator functionality to replace each().

Example from
https://www.nntp.perl.org/group/perl.perl5.porters/2023/11/msg267259.html:

my $it = iterator(\%ENV);
while (my ($key, $value) = $it->()) {
say "$key=$value";
}


The loop specific iterator variable could possibly allow access to info
such as "last iteration" in an easily nestable way. Not that I can readily
think how such a thing would be shaped. In the example implementation,
perhaps as a third argument returned from the iterator, but this is not
very extensible or intuitive.

-Dan
Re: Pre elevator pitch: Loop Info [ In reply to ]
On Tue, Jan 9, 2024 at 6:47?PM Leon Timmermans <fawaka@gmail.com> wrote:

> On Sun, Jan 7, 2024 at 5:16?PM Paul Webster via perl5-porters <
> perl5-porters@perl.org> wrote:
>
>> Hello All,
>>
>> I would like to get opinions from the community on a change I would like
>> to see, so I thought I write my PrePPC in the style as defined on
>> https://github.com/Perl/PPCs
>>
>> So keeping it short and sweet, here is my thinking:
>>
>> Here is a problem.
>> I cannot without adding additional code find out what positing in
>> an index I am presently processing, nor can I tell if I am on the final
>> iteration.
>>
>> Here is the syntax that I’m proposing.
>> ${^LOOPCOUNT} and ${^LOOPINDEX} (Naming is not final, willing to
>> change if people would prefer something else}, available in every FOR &
>> FOREACH.
>>
>> Here are the benefits of this.
>> No more $i’s everywhere being untidy.
>> Removing the constant questions regarding this very functionality
>> that seem to have happened frequently since the birth of Perl.
>>
>> Here are the potential problems.
>> Minor overhead added to all loops, though perhaps this could be a
>> triggerable feature requiring a “use feature ‘infoloop’” or such.
>>
>> Thank you for reading ????
>>
>
> I really hate the idea of using a magical variable for this for many
> reasons, its unnestability being the most obvious one.
>
> Clearly, functionality similar to ${^LOOPINDEX} should be possible by
> using a multivar for loop and a helper function. E.g.
>
> for my ($index,$value) (kv(@values)) { ... }
>
> That doesn't actually require any extension of the language (though
> multivar for is still experimental).
>

Also want to note, we have such a helper function (yet experimental) in
builtin now: https://perldoc.perl.org/builtin#indexed

-Dan
Re: Pre elevator pitch: Loop Info [ In reply to ]
I don’t think this is needed in core, I’m sure something already exists on cpan.

forEach(list, sub { my ($val, $index, $count) = @_; … });

If it was added to core I would prefer keywords // constants // context aware functions that return booleans for first and last iteration (as I can’t think of any other logical way they will be used) and an integer for index, but then it’s a shame ‘last’ and 'index' are already taken.

foreach my $val (@array) {
if (start) return ‘first';
elsif (end) return ‘last’;
else return itteration;
}

I guess type could be useful as well but depending on how it’s implemented it's all overhead for something you may or may not need.

If (type == ‘ARRAY’) { … }

Regards

LNATION.

Everyone can recognise history when it happens. Everyone can recognise history after is has happened; but only the wise man knows at the moment.
Re: Pre elevator pitch: Loop Info [ In reply to ]
On Tue, 9 Jan 2024 at 13:15, Dave Mitchell <davem@iabyn.com> wrote:

>
> First, an observation.
>
> In a perl for loop you can't, in general, pre-determine the number of
> iterations there will be, nor can you tell whether you are currently on
> the last iteration. For example:
>
> @a = (1,2,3);
>
> for (@a) {
> push @a, 4 if $_ == 3;
> print "$_\n";
> }
>
> which outputs 1..4. You can have similar weirdness by shortening @a
> mid-iteration. Furthermore, @a may be tied.
>
> And now onto some opinions.
>
> We absolutely should not use global special variables, i.e. $^{...}. If a
> variable is needed, it should be lexical (possibly implicitly so) and be
> declared as part of the 'for' syntax, e.g.
>
> for my $x :$i (...) { ... }
> or
> for my ($x, $y) ->$i (...) { ... }
>
> (those aren't firm proposals, just examples)
>
> Anything which requires extra work will slow down iteration. At a minimum,
> it will require an extra flag check per iteration to decide whether it can
> skip the increment code.
>

Great summary, Dave.

Based on this, imho only possible core implementation not harming (maybe
improving) performance is to provide
loop-state aware block implementing following:

if (!! @array) {
initially->();
for my ($index, $value) (builtin::indexed @array) {
}
finally->();
}

with syntax:

for my ($index, $value (builtin::indexed @array) {
}
initially {
}
finally {
}

but have to admit this approach doesn't handle modification of @array in
loop, so you cannot do:
for my ($index, $value) (builtin::indexed @array) {
push @array, 4 if $index == 1;
}

That imho can be done only by implementing iterators / generators
internally (like some other languages have).

Best way (will help to solving one of my problems with independent symbol
spaces) will be to extend each av_ function with (for example av_len):

if (av->virtual) {
return av->virtual->table->av_len (av, av->virtual);
}

virtual_table entry should be list (single-linked for next, double-linked
for capability to easily insert / remove behavior modifications).
struct {
next ... pointer to next;
void * data ... binding data (eg data contract cache)
table ... struct {
av_len;
av_...;
}
}

this approach will solve also not-exists storage problem (demonstrating on
scalar):

S_core_sv_exists (SV * sv, SV_VT * vt) { return 1; }

S_not_exists_sv_exists (SV * sv, SV_VT * vt) { return 0; }

S_not_exists_sv_setrv_inc (SV * sv, SV_VT * vt, SV * ref) {
if (sv_exists (ref)) {
vt->next->table->sv_setrv_inc (sv, vt->next, ref);
vt_remove (vt);
}
}

Best regards,
Brano
Re: Pre elevator pitch: Loop Info [ In reply to ]
Op 10-01-2024 om 07:49 schreef Branislav Zahradník:
>
>
> That imho can be done only by implementing iterators / generators
> internally (like some other languages have).
>

Which would be a GREAT addition to the language!


M4