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

Re: private recursive subroutines

by demerphq (Chancellor)
on May 10, 2007 at 18:47 UTC ( [id://614733]=note: print w/replies, xml ) Need Help??


in reply to private recursive subroutines

Other alternatives have been shown elsewhere in this thread, but one that Perlmonks uses (for reasons that are not worth getting into) is to do

local *foo= sub { my ($param)= @_; do { something }; foo($param); }; foo(...);

This approach has the nice benefit of benefit of being a touch more readable and avoids the memory leak when using the lexically scoped var variant (as ambrus mentions elsewhere). On the other hand it spoils the method cache which can cause a general slowdown for OO. YMMV.

---
$world=~s/war/peace/g

Replies are listed 'Best First'.
Re^2: private recursive subroutines
by ambrus (Abbot) on May 11, 2007 at 09:34 UTC

    In fact, it was diotalevi who taught me that my $f; $f = sub { ... &$f(...) ...}; leaks memory but the Y-combinator version my $g = sub { my $s = shift; ... &$s($s, ...) ... }; my $f = sub { &$g($g, @_) }; does not.

    That was when I showed him the Y-combinatored version of a function for pureness (no side-effects). I didn't really need that because the function was global so I could have used side-effects (the memory leak wasn't an issue because it's a garbage-collected language). At that time, I didn't know that it has a practical application in perl because of the reference counting. You can find that implementation here: t2n.olv (source), t2n.pl (compiled to prolog), t2n.sml (compiled to sml), olvashato/ (link to all files).

    Btw, diotalevi also claimed that this memory leak issue is described somewhere in Higher Order Perl, but I couldn't find it in that book. I'd be greatful if anyone can point me to the exact place.

      Btw, diotalevi also claimed that this memory leak issue is described somewhere in Higher Order Perl, but I couldn't find it in that book. I'd be greatful if anyone can point me to the exact place.

      No. MJD ignored the problem and hoped p5p would solve it. That's not entirely unreasonable since this usage is common but it doesn't seem like its fix is immanent.

      ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

        That's wierd, because I thought there was no way to fix this bug without a different garbage collector.

        On the other hand, I hope that the my $x; sub { sub { $x } } bug will be fixed by p5p, though I know nothing of its technical details.

Re^2: private recursive subroutines
by clinton (Priest) on May 11, 2007 at 09:46 UTC
    local *foo= sub { my ($param)= @_; do { something }; foo($param); };

    ... On the other hand it spoils the method cache which can cause a general slowdown for OO.

    demerphq, would you mind explaining this a bit?

    • How does the method cache work?
    • Which part of the above spoils it?
    • And what effect does it have on the cache?
    thanks

    clint

      From my limited understanding, the method cache allows Perl to remember to which function a method call resolves so it doesn't have to traverse @ISA every time.

      Changing the symbol table clears the cache. the value of *foo changes twice in the snippet in your post, the explicit assignment and the implicit assignment at the end of local's scope.

      $o->method(); # Normal (first call) $o->method(); # Faster due to cache *foo = sub {}; $o->method(); # Normal (cache cleared) $o->method(); # Faster due to cache

        Thanks, this is pretty much the response I would have made. The only thing I'd add is that as far as I understand things Perl 5.10 wont pay the same global penalty, rather the penalty will be restricted to the package or method itself, although I'm not sure which. This a side effect of Brandon Black's MRO patch for adding C3 style method resolution support to Perl.

        ---
        $world=~s/war/peace/g

        ok - but that hit is taken when the sub is inserted into the symbol table. Assuming you don't every redefine the sub, you can use it without messing with the method cache, no?

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (3)
As of 2024-04-19 22:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found