Are perl6 subs really lexically scoped or have extra?
When Perl6 comes across a function call it makes a note about it, but it does not check if the function is there.
So the following will compile, but will not actually work. (The function is not available where it is called.)
foo 1;
my &foo = &say;
In the following the compiler does the same thing, but then the optimizer realizes that it can't even find a reference to the function anywhere. (So the optimizer causes it to fail during compilation.)
bar 1;
The reason for this difference to other variables is that many times you may have one function that relies on another, or you want to place the functions after the rest of the code.
Also the code of a function is usually known at compile-time, whereas the value of a variable isn't known until after it is assigned. (The assignment happens at run-time.)
Basically the way people tend to use variables and functions is different, so they work slightly differently.
There isn't a need to require them to be declared before they are used, so that restriction was removed.
In Perl5 functions modify the parser based on their prototype, so the compiler needs to see a declaration before they are used for it to know how they should be parsed.
use v5.10;
sub foo ();
sub bar;
say foo + 1; # foo() + 1 # foo is compiled as a term/constant
say bar + 1; # bar( +1 )
sub foo () { 2 }
sub bar { $_[0] + 2 }
In Perl6 all functions are compiled as if they take a list, so there is no need to require them to be predeclared.
use v6;
# these two lines don't really change anything.
sub foo () {...}
sub bar ($) {...}
say foo + 1; # foo( +1 ) # optimization failure (too many arguments)
say bar + 1; # bar( +1 )
sub foo () { 2 }
sub bar ( $a ) { $a + 2 }
From the Subroutine Apocalypse:
Perl 6 also allows you to defer declaring your subroutine till later in the file, but only if the delayed declaration declares the sub to be parsed consistent with how a list operator would be parsed. Basically, any unrecognized "bareword" is assumed to be a provisional list operator that must be declared by the end of the current compilation unit.