my %dispatch = (); sub and_maker { my $num_args = shift; return $dispatch{$num_args} if $dispatch{$num_args}; my $built = join '&', map {'$_[' . $_ . ']'} (0..$num_args - 1); return $dispatch{$num_args} = eval "sub { $built }"; } Call as: my $func = and_maker(3); my $results1 = $func->(1,2,3); # 3 args my $results2 = $func->(5,6,7); # 3 args my $func2 = and_maker(5); my $$results3 = $func2->(12,13,14,15,16); # 5 args