Open In App

Perl – Closure Function

Closure is one of the important concepts in Perl. Closure is a computer term with an accurate but a hard to explain meaning. It is often referred as a function that can be stored as a variable, which has a special ability to access other variables local to the scope it was created in. It is used to refer to any of the outer function’s local variable and when the compiler detects that, it moves these variables to the closure’s hidden object declaration from the outer function’s stack space. It then generates a variable of closure type.
So basically, a function that captures the lexical environment in which it is created – i.e it runs around collecting all the things in the environment at that time is known as a closure function.

Closure with respect to the Perl language means that: subroutine 1 returns some other subroutine 2, then subroutine 2 accesses the variable x present in subroutine 1 and when the execution of the subroutine 1 ends, the user can no longer access x, but the subroutine 2 because also refers to the variable x point to the data object. It makes subroutine 2 continue to access this data object after the end of subroutine 1.
Therefore, the variable x in subroutine 1 must be a lexical variable, otherwise, after the execution of subroutine 1, the variable x may still be accessed by the outside world, modify, if so, the closure and the normal function is meaningless.

A closure is a type of function that is bound to a certain environment and is written as a function inside of another function.



Example:




sub make_adder 
{
    my $addpiece = shift;
    return sub { shift() + $addpiece };
}
  
# Driver Code
my $f1 = make_adder(555);
my $f2 = make_adder(20);

Now $f1($n) is always 555 plus whatever $n you pass in, whereas $f2($n) is always 20 plus whatever $n you pass in. The $addpiece in the closure sticks around.



Uses of Closures

Closures are really useful things. For example for callbacks, instead of passing a callback function pointer + argument in a function, and having to work out in that function what you’ve been called back with, one can just use a closure. When that function is called, it has access to all the lexical environment of when it was created.

Some of the main uses of closure are: Using them as ‘smart’ callback and the other one is using them as Iterators.

Use of Partial Application

The partial application function is known as the ability to take a function having many parameters and apply arguments to some of those parameters to create a new function that requires application of only the remaining arguments to produce the equivalent of applying the arguments to the original function.
The recurring feature of partial application is that when it is applied to a parameter, other parameters are not supposed to be mentioned explicitly.

Example:




sub fs(&) 
    my $func = shift;
    sub { map $func->($_), @_ }
}
    
sub double($) { shift() * 2 }
sub square($) { shift() ** 2 }
    
my $fs_square = fs(\&square);
my $fs_double = fs(\&double);
    
my @s = 0 .. 3;
print "fs_square(@s): @{[ $fs_square->(@s) ]}\n";
print "fs_double(@s): @{[ $fs_double->(@s) ]}\n";
    
@s = (2, 4, 6, 8);
print "fs_square(@s): @{[ $fs_square->(@s) ]}\n";
print "fs_double(@s): @{[ $fs_double->(@s) ]}\n";

Output:

fs_square(0 1 2 3): 0 1 4 9
fs_double(0 1 2 3): 0 2 4 6
fs_square(2 4 6 8): 4 16 36 64
fs_double(2 4 6 8): 4 8 12 16

Article Tags :