Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re^11: Why does each() always re-evaluate its argument? ("for_list" )

by NERDVANA (Deacon)
on Dec 08, 2023 at 05:41 UTC ( [id://11156190]=note: print w/replies, xml ) Need Help??


in reply to Re^10: Why does each() always re-evaluate its argument? ("for_list" )
in thread Why does each() always re-evaluate its argument?

Interestingly that topic came up on perl-porters a while ago and the conclusion is that it would be possible to make standalone iterator objects for hashes in several ways, but with different costs for different modes of failure. For instance, do you throw an error if the hash gets modified during iteration? or just warn and resume the iteration as best as possible? or not even warn? or (for a performance hit) implement a fully intuitive handling of deletions and insertions?

Several ways are possible right now using XS, without changing any core data structures. But, using the iterator would involve an XS function call, and be less performant than native iteration.

  • Comment on Re^11: Why does each() always re-evaluate its argument? ("for_list" )

Replies are listed 'Best First'.
Re^12: Why does each() always re-evaluate its argument? ("for_list" )
by ikegami (Patriarch) on Dec 08, 2023 at 17:21 UTC

    Yeah. I touched on this in my first post. The only thing Perl lacks is the syntactical sugar to make it nice ...which could probably also be added by a module (but it would be a lot more solid if built in).

    using the iterator would involve an XS function call

    No, that can be optimized away. See Syntax::Feature::Loop and Syntax::Feature::QwComments. Specifically this. (I think were broken by 5.38, but I intend to fix soon.)

      It appears Devel::CallParser was broken in 5.37, so that'd be the first place to look. Interesting module...
Re^12: Why does each() always re-evaluate its argument? ("for_list" inconsistent)
by LanX (Saint) on Dec 08, 2023 at 17:13 UTC
    I think consistency should have the top priority, and for_list should act like other for loops do.

    For-loop over an array will silently skip over deleted elements, hence a for-loop over a hash should too. (no tested yet)

    If a warning should be activated, then in both cases alike.

    update

    unfortunately it's NOT consistent

    $ cat tst_del.pl use v5.14; use experimental "for_list"; my %h; @h{"a".."d"} = 1..4; my @a = values %h; my $once; $once = 0; for my $e (@a) { splice @a,0,2 unless $once++; say "A: $e"; } $once = 0; for my ($k,$v) (%h) { delete @h{"a".."b"} unless $once++; say "H: $k => $v"; } say "never reached"; $ perl tst_del.pl A: 1 A: 3 H: a => 1 H: d => 4 Use of freed value in iteration at tst_del.pl line 22. $ perl -v This is perl 5, version 38, subversion 2 (v5.38.2)

    update

    tho, according to from perlsyn it's undefined behavior

    If any part of LIST is an array, "foreach" will get very confused +if you add or remove elements within the loop body, for example with "spl +ice". So don't do that.

    and the demonstrated results are quite unpredictable.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11156190]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2024-04-20 02:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found