Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

References for ano subs fixed at compile time?

by LanX (Canon)
on Jun 18, 2013 at 18:54 UTC ( #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)

Comment on References for ano subs fixed at compile time?
Select or Download Code
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

Re: References for ano subs fixed at compile time? (sorta)
by tye (Cardinal) 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 (Hermit) 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?
by dave_the_m (Parson) 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) /

Log In?
Username:
Password:

What's my password?
Create A New User
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? | Other CB clients
Other Users?
Others exploiting the Monastery: (9)
As of 2014-09-18 00:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (102 votes), past polls