Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^2: Closure confusion in Tkx (declarations in loops - inner vs outer)

by LanX (Saint)
on Jul 13, 2019 at 13:53 UTC ( [id://11102793]=note: print w/replies, xml ) Need Help??


in reply to Re: Closure confusion in Tkx (declarations in loops)
in thread Closure confusion in Tkx

> ²) a c-style for is semantically just a while-loop with a prior declaration.

to expand further on this, please see perlsyn#For-Loops

which means

for (my $i = 1; $i < 10; $i++) { ... }
is the same as this:

{ my $i = 1; while ($i < 10) { ... } continue { $i++; } }

now compare the different effects from an inner declaration ($i) and an outer declaration ($x)

use strict; use warnings; # ---------- for c-style my @cfor; for ( my $x = 1 ; $x < 4; $x++ ) { my $i = $x; push @cfor, sub { warn "cfor: \ti=$i \tx=$x" }; } $_->() for @cfor; # ---------- while my @values = 1..3; my @while; my $x; while ( my $i = shift @values ) { $x = $i; push @while, sub { warn "while: \ti=$i \tx=$x" }; } $_->() for @while;
cfor: i=1 x=4 at d:/exp/pm_closure2.pl line 11. cfor: i=2 x=4 at d:/exp/pm_closure2.pl line 11. cfor: i=3 x=4 at d:/exp/pm_closure2.pl line 11. while: i=1 x=3 at d:/exp/pm_closure2.pl line 25. while: i=2 x=3 at d:/exp/pm_closure2.pl line 25. while: i=3 x=3 at d:/exp/pm_closure2.pl line 25.

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Replies are listed 'Best First'.
Re^3: Closure confusion in Tkx (declarations in loops - inner vs outer)
by lbrandewie (Acolyte) on Jul 13, 2019 at 20:28 UTC

    Thanks Rolf!

    The code works now but I'm still kinda puzzled as to why the c-style for fails in this case. Is this not a bug in perl?

    Regards,

    Lars

      I agree with LanX's explanation here, but here's something I put together that may provide a different viewpoint.

      In the C-style for-loop and in its while-loop equivalent in LanX's examples here, a closure is formed (if that's the correct term) over two variables, $i and $x. The $i variable is created anew in each iteration through each loop (there's a  my $i = ...; within the scope of the loop), but the $x variable is created only once (in each example). Therefore, the closures are over three different versions of a variable named $i, each of which can have a different value, but only over a single version of a variable named $x, which has the value it ends up with at the end of each of the loops.

      In the Perl-style loop example here, the for-loop iterator variable $i is successively aliased to three individual values, each of which individually has a closure formed over it and so can reflect those three values independently; you're seeing the alias of $i in each case and not the value of $i.

      Or so I think...

      Update: And no, the way the C-style for-loop works in Perl is not a bug; it's the way closures work.


      Give a man a fish:  <%-{-{-{-<

      > as to why the c-style for fails in this case.

      Think of lexicals in a scope like having a different references each time the scope is passed at runtime.

      But - like already demonstrated - the first part of the c-style for is outside the block to be implemented as a while.

      More gory details?

      A lexical declaration in a scope reserves - at run time - a storage place in memory which is released at the end of scope.

      No release happens if the ref counter isn't 0, like when the lexical is used in a closure.

      So if the last lexical was released it might happen that the ref is reused, but it's better to assume they aren't the same variable.

      DB<8> for my $x (1..3) { print \$x } SCALAR(0x3450e50)SCALAR(0x3450e50)SCALAR(0x3450e50) DB<9> for my $x (1..2) { print \$x; $a = sub {$x} } SCALAR(0x3459b20)SCALAR(0x3328238)

      $x has different refs in line 9 because the first $x is captured in a closure and not relased.

      Hence Perl can't reuse the reference.

      HTH! :)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2024-04-19 02:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found