Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • Don't those kinds of closures leak (anonymous recursive subs, that is), unless maybe you use maybe Scalar::Util::weaken or one of those combinator [] -type thingies (or some Devel::* module I think or something else)? Or do you really even care in this instance? :-)
    • I don't think they leak - there were some bugs with eval blocks and anonymous subs, but I think all those leaks have been closed now.

      This design is used a lot by IO::AIO (which is used in some people's production apps) and thus if it leaked we would find out about it darn fast.
      • I thought it happened whenever you had the my $sub; $sub = sub { ...$sub... }; construct, and that whenever that code got called, the reference count for $sub would never go to zero. Is what you're doing any different than this (leaks in 5.8), or did this sort of thing recently get fixed?:

        my $foo = sub {
          my $sub;
          $sub = sub {

        my $i;
        print "Start: ";
        while (++$i) {
          my $f = $foo->();
          unless ( $i % 100_000 ) {
            print "$i: ";

        • That does indeed seem to leak, but it's fixed by adding weaken($sub) inside the anonymous sub, so that's no big deal to me. Thanks for the heads up though.
          • I know weaken() was one of the options, but I'm trying to become a functional weenie, so I'm starting to like the combinator approach (this example ripped and tweaked from the Moose source):

            sub U {
                my $f = shift;
                sub { $f->($f, @_) };

            sub Y {
                my $f = shift;
                U(sub { my $h = shift; sub { $f->(U($h)->())->(@_) } })->();

            # Now we need a recursive anonymous function
            my $fact = Y(sub {
              my $f = shift;
              sub {
                my $n = shift;

            • by Matts (1087) on 2006.09.01 20:03 (#49726) Journal
              Yeah, it's just a shame that code is so cryptic. No wonder perl gets a bad rap (though I guess it's copied from some lamda calculus stuff). You'd think they could use more than single character variables and function names for it all.
              • I agree that the Y() is cryptic (and you can't blame perl too much), but the U() is not that hard to understand, and if they're tucked away in a library (as they are in Moose::Autobox albeit in an OO form), then you don't have to look at them, and they're pretty simple to use. In other words, "don't look behind the curtain, just use the Y-combinator" :-)

                If you have freedom in what args your recursive sub accepts (which I assume you don't in the above instance), then you can let the first arg be the sub its

              • It’s the construct that’s cryptic, not the Perl code. It’s no easier to understand in Lisp, although the core concept is actually very simple. The basic idea is that you make an anonymous function recursive by making it take a reference to itself as a parameter, so that it can call that to recurse on itself.

                The actual implementation requires doing a series of code sit-ups that makes the fully built combinator very hard to follow. I think I’ll have to rewrite it for myself in Pe

                • I think decently named params would make it understandable.
                  • I would usually agree but in this case I don’t see how. Using $func or $closure in place of $f wouldn’t do anything to clarify any of what’s going on, and I can’t think of any good name of $h. The functions are no easier to name more sensibly. It would help the legibility of the Y combinator to break it down a bit and assign subexpressions to suitably named variables, but the difference wouldn’t be anything to write home about.

                    These are simply near-unreadable constructs.

                    • So here's where I'm coming from: The Y combinator is useless in the code I showed, because $sub isn't called explicitly - it's a callback. So having the Y combinator re-written to be more readable, with better variable names, and comments, might allow me to write a version specifically for my code that doesn't require the use of weaken().
                    • In practice these things just don’t need to be readable once you get one working;

                      That sums up my frustrations with higher order mathematics pretty effectively. I strongly suspect that the Haskell compiler rejects identifiers with more than one vowel or over eight characters, but I can't prove it, for example.

                    • I suppose. I can’t read the Y combinator either, y’know. I can derive it when I start from scratch, though, and for as long as that model is in my head, I can reason about it.

                      I just can’t build it inductively from reading the source/expression. I have to deduce it every time from scratch.

                      It may be a matter of practice.