in reply to Re^4: Why are closures cool?
in thread Why are closures cool?

What is correct?

I had never before heard the accusation that Perl closures are not what is normally considered a closure. The issue that runrig pointed out is that trying to mix the semantics of package names with closures allows situations which cannot be resolved properly. But use closures around anonymous functions and things work perfectly well.

Do you have a specific example of how Perl's closures should do something other than what they do?

Replies are listed 'Best First'.
Re: Re (tilly) 5: Why are closures cool?
by demerphq (Chancellor) on Jan 14, 2002 at 18:35 UTC
    trying to mix the semantics of package names with closures allows situations which cannot be resolved properly.

    Actually my understanding of this (from the perl5porters list I think..) is that this and other weaknesses of the closure mechanism are due to implementation issues in perl, not that they aren't resolvable in general.

    Also you asked me over chatter as to how I would like perl to handle named closures, to which I have two answers. The first (non preferred option) would be that they should be handled exactly as they are in anonymous subroutines. (IE the variables _should_ be shared.) However what I would prefer to see is pascal style nested subroutines (lacking from most languages (ie C) due to implementation difficulties iirc). In this model the inner subroutine should have access to the outer subs declared variables, but should not be visible out of that scope. This would (IMHO) make writing recursive algorithms much cleaner and more elegant. Something like this would be nice..

    sub recurse_postorder { my $self=shift; my $debug=shift; my @list; sub _recurse { my $node=shift; my $depth=shift; print ("\t"x$depth)."$node->{value}\n" if $debug; _recurse($node->{left},$depth+1); _recurse($node->{right},$depth+1); push @list,$node->{value}; } _recurse($self->{root},0); return \@list; }
    Anyway, I know your standing joke about pascal so my guess is you wont like the idea, but personally nested subs, with structures and case statements are the three pascal features I would most like to see added in perl6.

    Yves / DeMerphq
    --
    When to use Prototypes?

      First of all what you heard on p5p is correct. The code example that I gave at Re (tilly) 9: Why are closures cool? makes it clear that there is no good resolution of the named/lexical issue.

      As for the second, it is possible already:

      sub recurse_postorder { my $self=shift; my $debug=shift; my @list; my $recurser; $recurser = sub { my $node=shift; my $depth=shift; print ("\t"x$depth)."$node->{value}\n" if $debug; $recurser->($node->{left},$depth+1); $recurser->($node->{right},$depth+1); push @list,$node->{value}; }; $recurser->($self->{root},0); return \@list; }
      OK, so the cost is that you have to use anonymous functions and a slightly unusual syntax. But that is fixable as well - just use the syntax all of the time and it is no longer unusual for you! (This has been suggested seriously before because it allows strict.pm to catch typos in function names.)

      The bigger cost is that the function is never garbage collected. You can partially fix this by doing an undef on the function. I say partially because there is an outstanding bug where it still doesn't get garbage collection. But ignoring the garbage issue, it is here and works. :-)

Re^6: Why are closures cool?
by Aristotle (Chancellor) on Jan 13, 2002 at 08:36 UTC
    "Correct" as in how they work in the languages that originally introduced the concept and the term.
      You did not provide me with the code example I requested.

      Please give me, for instance, a simple Scheme example showing the desired behaviour of closures that you think that Perl does not support. I doubt I will have any problem in translating it.

      Now to avoid the naming problem above I will need to avoid (for obvious reasons) having the inner subroutine be given a potentially ambiguous global name. But that is a minor detail, and there are many ways around it in practice.

        All I said is that the semantics differ from LISP's in Perl, since subroutine names (and in fact, named subroutines as a whole) aren't lexicaly scoped, with no assertion on whether it is possible to fully emulate it using anonymous subs. If you look back at my previous post you'll see this:

        I don't see much of a point to using named subsubroutines [in Perl] - unless you want to pass it around as a reference, in which case you didn't do anything less than you would have had to with an anonymous sub.

        It was just nitpicking - nay, less even, I just agreed with runrig's nitpickery. If you look back, you'll see I wasn't even arguing, I inquired about his point then agreed after explanation.