Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

References for ano subs fixed at compile time?

by LanX (Saint)
on Jun 18, 2013 at 18:54 UTC ( [id://1039629]=perlquestion: print w/replies, xml ) Need Help??

LanX has asked for the wisdom of the Perl Monks concerning the following question:

Hi

I'm pretty sure the answer is yes, but to be sure:

Are the references to anonymous code blocks in Perl always constant, because they are fixed at compile time?

DB<115> sub tst (&) { print "$_[0]\n" } DB<116> tst {1,2,3,4} for 1..5 CODE(0xa396560) CODE(0xa396560) CODE(0xa396560) CODE(0xa396560) CODE(0xa396560)

Is it reliably so? I took a look at B::Concised opcode output and as far as could see it seemed so...

Please note that it is not the case for anonymous hashes

DB<118> sub tst (%) { print "$_[0]\n" } DB<119> tst {1,2,3,4} for 1..5 HASH(0xa3963f0) HASH(0xa396940) HASH(0xa396720) HASH(0xa3966c0) HASH(0xa3963f0)

Cheers Rolf

( addicted to the Perl Programming Language)

Replies are listed 'Best First'.
Re: References for ano subs fixed at compile time?
by dave_the_m (Monsignor) on Jun 18, 2013 at 22:51 UTC
    Here's how it it works. Consider the following code:
    $f = sub { .... };
    At compile time, the code within {} is compiled into a prototype anonymous sub (CV), which is squirrelled away somewhere. At run time, the action of sub {...} is to make a copy of that sub (allocating a new CV), and then return a reference to that new CV.

    As an optimisation, if the sub isn't a closure, then rather than copying the CV, a reference is just returned to the original prototype CV. This optimisation isn't perfect; in particular if one blesses $f, then the prototype CV gets blessed, and any new executions of that $f = sub {...} assignment get a blessed coderef.

    Finally, note that perl maintains a pool of spare CVs; when one is freed, it gets returned to the pool and that may get reused soon.

    Of course, these are implementation details which are subject to change.

    Dave.

      Demonstration:
      sub f(&) { my ($cr) = @_; push @keep_alive, $cr; say $cr; } my $x = '...'; f { '...' } for 1..2; f { $x } for 1..2;
      CODE(0x3396f4) \ same for non-capturing CODE(0x3396f4) / CODE(0x24b1cc) \ different for capturing CODE(0x338c04) /
Re: References for ano subs fixed at compile time? (sorta)
by tye (Sage) on Jun 18, 2013 at 20:03 UTC

    If a sub doesn't close over any lexicals, than I bet that refs to it will be constant. If subs close over lexicals (or represent different code), than the refs can't be constant unless the refs have non-overlapping lifespans.

    DB> sub test(&) { my( $c ) = @_; print 0+$c,$/; return $c } DB> ;{ my($a,$b); test {$a}; test {$b} } 14808916 14808916 DB> ;{ my($a,$b); my $c = test {$a}; test {$b} } 15512116 15512804 DB> ;{ my @a; for(1..3){ my $a; push @a, test {$a} } } 15513028 15511044 15513252

    - tye        

      the last case is the interesting one for me, the coderef of a block at a fixed position (and therefore the same code). I don't care if other blocks get the same ref after this one gets destroyed.

      And my test with your code shows that the ref is fix if its not returned:

      DB<123> sub test(&) { my( $c ) = @_; print 0+$c,$/; return $c } DB<124> ;{ my @a; for(1..3){ my $a; push @a, test {$a} } } 145187472 145182504 144725160 => "" DB<125> sub test(&) { my( $c ) = @_; print 0+$c,$/} DB<126> ;{ my @a; for(1..3){ my $a; push @a, test {$a} } } 145184216 145184216 145184216 => ""

      So the ref is chosen dynamically from a pool of available refs, it can be the last one if it has been released before.

      Thx! =)

      UPDATE

      OK the following code shatters all my hopes that I found an answer to an old question ...

      DB<155> sub tst2(&) { my( $c ) = @_; print &$c,":\t",0+$c,$/;return +$c} DB<156> sub tst1(&) { my( $c ) = @_; print &$c,":\t",0+$c,$/;} DB<157> ;{ my $b; for my $a (1..3){tst1 {$a} ; $b=tst2 {42} if $a==1 + } } 1: 145234328 42: 145234328 2: 141318480 3: 141318480

      it doesn't matter how tst1() deals with the coderef, any later coderef generation might bind the address and disable it for other use.

      > If a sub doesn't close over any lexicals, than I bet that refs to it will be constant.

      Nope it doesn't matter if there are closed over variables, unfortunately you loose your bet...

      DB<158> ;{ my $b; for my $a (1..3){tst1 {1} ; $b=tst2 {2} if $a==1 } + } 1: 141317840 2: 141317840 1: 141318608 1: 141318608

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        Nope it doesn't matter if there are closed over variables, unfortunately you loose your bet...

        To quote myself, with emphasis added:

        If subs close over lexicals (or represent different code)

        "sub {1}" and "sub {2}" are two different subroutines, even when you use prototypes to make the "sub" keyword implied rather than explicit.

        - tye        

Re: References for ano subs fixed at compile time?
by Eily (Monsignor) on Jun 18, 2013 at 21:24 UTC

    I ran a few tests after Anonymous Monk's post with

    $\=$/; sub tst { print shift } sub ptst(&) { print shift } sub ff { tst sub {1, 2, 3,} } ff for (1..3); sub ff { print sub {1, 2, 5,} } ff for (1..3); sub ff { ptst {1, 2, 4,} } ff for (1..3);

    Which gives in the debugger:

    DB<1> $\=$/; DB<2> sub tst { print shift } DB<3> sub ptst(&) { print shift } DB<4> sub ff { tst sub {1, 2, 3,} } ff for (1..3); CODE(0x2d1c1f8) CODE(0x2d1c840) CODE(0x2d1c828) DB<5> sub ff { print sub {1, 2, 5,} } ff for (1..3); CODE(0x2d1c330) CODE(0x2d1c330) CODE(0x2d1c330) DB<6> sub ff { ptst {1, 2, 4,} } ff for (1..3); CODE(0x2d1c8a0) CODE(0x2d1c930) CODE(0x2d1c8e8)

    Though there are still things I don't get (like the fact that user function versus core function matters), I interpreted it as proving AM right. Except I ran the following code as a file instead of in the debugger.

    $\=$/; sub ptst(&) { print shift } sub ff {ptst {1, 2, 3, 4,} } ff for (1..3); ptst {1, 2, 3, 4,};

    With the output:

    CODE(0x20f2b8) CODE(0x20f2b8) CODE(0x20f2b8)

    Where you'd get different references with a (%) prototype for ptst. I guess perl is just too smart for me.

Re: References for ano subs fixed at compile time? (no)
by Anonymous Monk on Jun 18, 2013 at 19:29 UTC

    Are the references to anonymous code blocks in Perl always constant, because they are fixed at compile time?

    No and no; its just another variable. consider

    $ perl -le " for(1..3){ my$f=$_; print\$f; }" SCALAR(0x99b824) SCALAR(0x99b824) SCALAR(0x99b824)

    versus

    $ perl -le " sub ff { my $f = $_; return \$f } print ff() for 1..3;" SCALAR(0x3f9bcc) SCALAR(0x3f9bbc) SCALAR(0x3f9bcc)

    What perl does, how perl optimizes, how perl reuses allocated memory, depends on what the code does

      I was talking about CODE-refs not SCALARs!

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        I was talking about CODE-refs not SCALARs!

        Same difference, perl reuses references as it sees fit

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1039629]
Approved by BrowserUk
Front-paged by BrowserUk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (4)
As of 2024-04-18 03:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found