All the Perl that's Practical to Extract and Report

Navigation

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
Without JavaScript enabled, you might want to
use the classic discussion system instead. If you login, you can remember this preference.

Please Log In to Continue

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 [perl.org] -type thingies (or some Devel::* module I think or something else)? Or do you really even care in this instance?:-)

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?:

So here's a version that doesn't leak, that uses this approach, and isn't so darn cryptic:

# wrap an anonymous function into a function that takes $func as the first# parameter so we can make use of it from within the call.sub wrap_func { my $func = shift; return sub { $func->($func, @_) };}

Well yes, you get away without the Y combinator here. wrap_func is a rather nondescript name, though, don’t you agree? A better one might be something like curry_self or apply_self_maker or some such, although it’s probably not obvious to someone without basic knowledge of functional programming why these names are in fact better. All of them sound similarly meaningless, though the better ones might even be a little scary. And to someone with functional programming knowledge, U would be just as descriptive anyway; in fact, to such a programmer your choice of name is much worse than using U. So it’s not clear to me that you can gain actual clarity by “better” naming.

Note that you get away with the U combinator here, which is self-explanatory anyway. Try doing the same with the Y combinator and you’ll have a lot less luck.

If it’s not clear yet, I happen to think that understanding the Y combinator (what it’s for and how it’s derived) is an important part of any good programmer’s education. For a demonstration of why, just take note that your recursive function is broken. To fix it, change the last line:

$imap->message_info($i, $sub) unless $i == $nm; # no wrap_func

Applying the U combinator to itself does not yield the U combinator. So if you call wrap_function on the return of wrap_function, you will get an ever deeper onion of closures that apply the previous wrapper to itself plus their arguments, accumulating wrappers going down the layers, until finally the last wrapper applies the original function to itself plus all the wrappers plus the passed parameters. Ie. after four applications you’d have a wrapped wrapped wrapped wrapper equivalent to this:

Heh. I’d read about the Y combinator before but I only started studying it in anger yesterday because I realized I wouldn’t actually understand it on any deeper level if I didn’t sit down to derive it from first principles for myself.

My grasp is strengthening by the hour, but you can see I’m not quite there yet.:-)

: 1. What is the possibility of this being added in the future?
In the near future, the probability is close to zero. In the distant
future, I'll be dead, and posterity can do whatever they like... :-) --lwall

Stories, comments, journals, and other submissions on use Perl; are Copyright 1998-2006, their respective owners.