Stories
Slash Boxes
Comments
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.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Can you give an example of how this might make some code cleaner or more correct?

    • I had to chuckle at your subject. I certainly know the feeling. The upshot is that you can use this to write recursive anonymous closures (avoiding all side-effects).

      I did this as an excercise. I am tiptoeing into the functional world proper lately, but my stance to it remains ambivalent. Perl isn’t quite the most beautiful language, but I find it a whoooole lot easier to read than any Lisp. I doubt that will ever change, irrespective of practice – I find your lack of syntax disturbing. This meant I understood the explanations, but couldn’t grok the code samples in enough to detail for more than a superficial grasp. Hence the decision that I would need to redo this in Perl for myself.

      I don’t really have a good example on hand where you’d need to do this, or at least could use this to make something much easier. (Maybe I should page MJD here?) I assume that’s because we’re talking about Perl, where statements roam and side effects abound. A schemer could probably come up with a credible use case.

      If side effects are not an issue, you can achieve the same much easier in Perl:

      my $fac = do {
          my $f;
          $f = weaken sub {
              my ( $n ) = @_;
              $n < 2 ? 1 : $n * $f->( $n - 1 );
          };
      };

      (I think: untested. Does weaken return the reference? If not, it gets a good bit more awkward.)

      • You would need to do:
        my $fac = do {
            my $f;
            my $tmp = $f = sub {
                my ( $n ) = @_;
                $n < 2 ? 1 : $n * $f->( $n - 1 );
            };
            weaken($f);
            $f;
        };
        If you just weaken f without the tmp variable, you lose all references to it and it goes away before you have a chance to return it.
        • Ah yes, d’uh.

          But didn’t you mean your do {} block to return $tmp rather than $f? $f is the weak reference used inside the function, while $tmp is the strong reference you pass back out to the surrounding expression, no?

          • I don't think it matters which you return. As long as you are assigning $f to something (as above), there will still be a reference to it (from outside the scope of the do block) after $tmp goes out of scope.
            • Ah, when you copy a weak reference, the new reference is strong. Learn something new every day…

              In any case, the necessary code is rather unwieldy – enough so that I’d rather just use a Y combinator…

      • Not precisely... Weaken works on the variable, not the value. This should work:

        my $f;
        $f = sub { ... $f ... };
        weaken $f;
        return $f;
        • That doesn't work. As soon as you weaken $f, the code it refers to goes away because there are no other references to it. You need to keep another reference to it (hence the temp variable in a previous reply).