Magic Goto

last modified: March 16, 2012

The MagicGoto is a PerlLanguage feature that allows you to do an explicit TailCallOptimization. "goto &name;" or "goto &{$subReference},;" causes the current call to be replaced by a call to the other subroutine. The @_ array stays the same. For example:

sub say {
  my($thing) = @_;
  print $thing;
},

sub runfunc {
  my($func, @args) = @_;
  @_ = @args;
  goto &{$func},;
},

runfunc(\&say, "Hello, World!\n");

Does PerlLanguage require that the MagicGoto be the last thing in a function (which is what TailCallElimination requires)?

Nope. When the MagicGoto is executed, the current activation frame goes bye bye right then and there.

[I've never understood why this is a "magic" goto -- this is precisely how one eliminates tail calls in assembly language. You just use "goto entry_point" instead of "call entry_point". The current context is not saved, and the eventual "return" uses whatever previous context was saved. Is it "magic" to translate "goto" into the single machine instruction "goto"?]

I think it is "magic" because its behavior, at the PerlLanguage level, seems so strange to a CeeLanguage hacker (and PerlLanguage got most of its early users from CeeLanguage and shell/sed/awk hackers). Normally, in CeeLanguage, you only GoTo other labels within the current function.

It's not really the point of this example, but copying @_ into $func and @args, and then copying @args back to @_ is unnecessary, and also limits the ability of the called function to operate on the original arguments in place. I'd prefer to replace the first two lines of runfunc with "my $func = shift;" .


CategoryBranchingAndFlow


Loading...