in reply to map and return

Many of the builtin functions have special syntax that can not be described with prototypes. Actually even the syntax of prototyped functions is quite complicated, so you could even say the syntax of any one builtin is quite regular, the only problem is that there are more different kinds of builtins than there are prototypes.

As an example, let's look at how syntax of calling map is different from a sub you declare with (&@) prototype.

You can call map with the first argument being a bare expression followed by a comma or a braced block without a comma, and you can do either even if you put this first argument inside the function call parenthesis. For example, these four are equivalent.

print map ucfirst, "just another ", "perl hacker\n"; print map { ucfirst } "just another ", "perl hacker\n"; print map(ucfirst, "just another ", "perl hacker\n"); print map({ ucfirst } "just another ", "perl hacker\n");
If you use function call parenthesis, which must include the first argument, like in the last two lines, the rule that the function call ends at the closing parenthesis applies, so in the following statements "hacker" is not capitalized.
print map(ucfirst, "just another ", "perl "), "hacker\n"; print map({ ucfirst } "just another ", "perl "), "hacker\n";
In contrast, if you define a function like this,
sub mymap (&@) { map { &{$_[0]}() } @_[1..@_-1]; }
then you cannot call it with a bare expression as its first argument. You can call it with a bare block with or without a comma, provided you omit the parenthesis, so the following two are valid, but the second would not work with map.
print mymap { ucfirst } "just another ", "perl hacker\n"; print mymap { ucfirst }, "just another ", "perl hacker\n";
You can not add function call parenthesis if you use bare blocks. If you use an immediate sub block or certain restricted classes of expressions as the first argument, then you may add parenthesis, so the following work. Most expressions just don't work as first argument though.
print mymap sub { ucfirst }, "just another ", "perl hacker\n"; print mymap(sub { ucfirst }, "just another ", "perl hacker\n"); sub ucf { ucfirst }; print mymap \&ucf, "just another ", "perl hacker\ +n"; sub ucf { ucfirst }; print mymap(\&ucf, "just another ", "perl hacker\ +n"); $ucf = sub { ucfirst }; print mymap \&$ucf, "just another ", "perl hac +ker\n"; $ucf = sub { ucfirst }; print mymap(\&$ucf, "just another ", "perl hac +ker\n");