Writing recursive closures

I discovered the other day that you can do quite horrifying things with perl. A closure in perl is a nice concept – it’s a block that can reference things in the scope that it’s declared in, but that can be passed around and used in quite different scopes. For instance, suppose I wanted a function that, say, converted a string to utf8 bytes (yes, I’m obsessed with utf8). I can do this like this:

my $closure;
$closure = sub {
  my $val = shift;
  return Encode::encode("utf8", $val);
};

And call it later as:

print $closure->("héllo");

This is dead nifty. But because a closure can reference things in it’s scope, and $closure is in it’s scope, it can call itself, or at least, it can call the function pointed at by $closure. So we can make this function recursive:

$closure = sub {
  my $val = shift;
  if (ref $val eq "ARRAY") {
    return [ map { $closure->($_) } @$val ];
  } elsif (ref $val eq "HASH") {
    return { map { $_ => $closure->($_) } keys(%$val) };
  } else {
    return Encode::encode("utf8", $val);
  }
};

Until the assignment is complete, the inside of the closure won’t work, because $closure is undefined. But by the time we call it later..

return $closure->( [ "héllo", { foo =>"bår" } ] );

..everything works.

Crazy, I tell you.