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

Doesn't look broken to me... Am I missing something?

The 'brokenness' comes when you have a named sub inside another subroutine. If you try this:

use strict; use warnings; sub function { my $i = 0; sub test { print ++$i,"\n"; } test(); test(); }
You'll get a "variable will not stay shared" warning, and will not get the results you expect. This happens alot with Apache::Registry novices because people will write subroutines with global (i.e. my variables at the outermost scope) variables, and Apache::Registry wraps the entire script into a subroutine of its own, so you end up with a situation like the above (the answer being to not use globals, or put the subroutines and their globals into a package of their own).

Replies are listed 'Best First'.
Re^4: Why are closures cool?
by Aristotle (Chancellor) on Jan 13, 2002 at 01:38 UTC
    Oh. Well named subroutines always go into the "package scope" (is there a proper term for this?), so that code corresponds to
    use strict; use warnings; sub test { print ++$i,"\n"; } sub function { my $i = 0; test(); test(); }
    regardless of what you meant it to.

    And to be honest, I can live with that. I don't see much of a point to using named subsubroutines - 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. Right? Of course it is correct to point out that Perl's closures are not exactly equivalent to what is commonly referred to as a closure. (Though I think whether that makes them incomplete is debatable.)
      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?

        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?

        "Correct" as in how they work in the languages that originally introduced the concept and the term.