Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

Closure Explanation

by bichonfrise74 (Vicar)
on Apr 30, 2010 at 01:48 UTC ( #837669=perlquestion: print w/replies, xml ) Need Help??
bichonfrise74 has asked for the wisdom of the Perl Monks concerning the following question:

I got this code from this article
sub make_counter { my $start = shift; return sub { $start++ } } my $from_ten = make_counter(10); my $from_three = make_counter(3); print $from_ten->() . "\n"; print $from_ten->() . "\n"; print $from_three->() . "\n";
I tried to read the article on the explanation of the code above but I could not figure out how it is able to 'retain/remember' the old values.
Can someone further dissect or rewrite this code to show what is exactly happening?

Replies are listed 'Best First'.
Re: Closure Explanation
by AnomalousMonk (Chancellor) on Apr 30, 2010 at 02:56 UTC

    See Closure on Closures (and also How A Function Becomes Higher Order and How To: Make An Iterator) and their various 'Reply' and 'Also' sections for applications, amplifications, etc.

    I don't think I could come up with an explanation better than the above or than those contained in standard references. If you still have problems, you might try asking specific questions – with examples, if possible!

    BTW: I put these refs. together using Super Search on 'closure'!

    Update: Closure may also be helpful.

Re: Closure Explanation
by almut (Canon) on Apr 30, 2010 at 06:22 UTC

    Just think of it this way: when a function closes over a lexical variable, that instance of the variable (and its associated storage location) won't be freed, as it normally would when the variable goes out of scope — i.e. it continues to remain accessible to the function.

    Note that you can (in theory) have more than one closure sharing the same variable instance (kind of their private global variable). Extending the Anonymous Monk's code:

    #!/usr/bin/perl sub make_counter_pair { my $start = shift; warn "lexical variable ".\$start." created"; return ( sub { warn "accessing ".\$start; $start++ }, sub { warn "accessing ".\$start; $start++ } ) } my ($c1, $c2) = make_counter_pair(10); my ($c3, $c4) = make_counter_pair(3); print $c1->() . "\n"; print $c2->() . "\n"; print $c1->() . "\n"; print $c2->() . "\n"; print $c3->() . "\n"; print $c4->() . "\n"; print $c3->() . "\n"; print $c4->() . "\n";

    would give

    lexical variable SCALAR(0x604ff0) created at ./ line 5. lexical variable SCALAR(0x6323f0) created at ./ line 5. accessing SCALAR(0x604ff0) at ./ line 8. 10 accessing SCALAR(0x604ff0) at ./ line 12. 11 accessing SCALAR(0x604ff0) at ./ line 8. 12 accessing SCALAR(0x604ff0) at ./ line 12. 13 accessing SCALAR(0x6323f0) at ./ line 8. 3 accessing SCALAR(0x6323f0) at ./ line 12. 4 accessing SCALAR(0x6323f0) at ./ line 8. 5 accessing SCALAR(0x6323f0) at ./ line 12. 6

    As you can see by looking at the addresses, each pair of closures shares one variable, so the respective value is incremented every time one of the two counter functions is called.

Re: Closure Explanation
by Anonymous Monk on Apr 30, 2010 at 02:16 UTC
    sub make_counter { my $start = shift; return sub { warn \$start; $start++ } }
Re: Closure Explanation
by Anonymous Monk on Apr 30, 2010 at 18:35 UTC
    Is callback the same as closure in Perl?
      Closure example:
      sub rtn_closure { my $i = shift; return sub { $i++ }; } # f's i starts at 5 my $f = rtn_closure(5); print $f->(),"\n"; # Prints 5 print $f->(), "\n"; # Prints 6 # g gets a separate i that starts at 10 my $g = rtn_closure(10); print $g->(), "\n"; # Prints 10 print $g->(), "\n"; # Prints 11 print $f->(), "\n"; # Prints 7
      Callback example:
      sub exec_callback { my $f = shift; $f->(); } exec_callback(sub {print "hello\n"});
      Does that help? A callback does not have to close over any variables, although it could. A closure occurs whenever a function refers to a variable in an outer scope.

      No, a callback need not be closed over any variables. A closure may be called by any means a normal function is.

      TGI says moo

        Do you have a sample code showing the difference between the two?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://837669]
Approved by AnomalousMonk
Front-paged by ww
[Discipulus]: I already know how much distinct paths exists but to demonstrate the property i want to have them all
[oiskuu]: ie C(n, k); where n is height difference, k is position in the line
[Discipulus]: infact there are 70 distinct path to reach the tale wich holds 70
[Discipulus]: what i want is to compute them
[oiskuu]: You want to draw the path? $iter = combinations( $TOP_HEIGHT .. $NODE_HEIGHT, $pos); then get the path from the iter, level change at depth x, for(..) $pos += $level_change; something like that

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (9)
As of 2018-03-19 11:05 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (239 votes). Check out past polls.