{ my $move_disk; sub hanoi { $move_disk = pop(@_); goto &_hanoi; # (almost) equivalent to _hanoi(@_) } sub _hanoi { my ( $n, $start, $end, $extra ) = @_; if ( $n == 1 ) { $move_disk->( 1, $start, $end ); } else { _hanoi( $n - 1, $start, $extra, $end ); $move_disk->( $n, $start, $end ); _hanoi( $n - 1, $extra, $end, $start ); } }; } hanoi( 3, 'A', 'B', 'C', sub {print "(@_)\n"} );