Sawyer Sawyer - 10 months ago 40
Perl Question

How can I do function partial application in Perl?

Is there any way to achieve partial application in Perl?

Suppose, I want to do something like:

sub each_file($arr, $op) {
$op->($_) for @{$arr};

sub each_line($op, $file) {

each_file($arr, each_line($op));

I want to partially apply
to only
, so it'll become a new function can be passed to
, how do I express this in idiomatic Perl?

Answer Source

You can do this in Perl with two approaches combined:

  • A function which returns a function reference

  • Closures


sub each_file {
    my ($arr, $line_fn) = @_;
    $line_fn->($_) for @{$arr};

sub each_line {
    my ($op, $file) = @_;

sub make_line_processor {
  my ( $op ) = @_;

  # This is closed over $op, which effectively becomes 
  # a constant for the returned function
  my $fn = sub {
     return each_line( $op, @_ );
  return $fn;

# To call it:
each_file( $arr, make_line_processor($op) );

This can be an even more useful technique in cases where you don't want $op directly, but some expensive-to-fetch derivation of it. In which case you would calculate the derived value just once (in the make_line_processor function) and close over that instead.