Когда Perl6 сталкивается с вызовом функции, он записывает это, но не проверяет, есть ли функция.
Таким образом, следующее скомпилируется, но фактически не будет работать. (Функция недоступна там, где она вызывается.)
foo 1;
my &foo = &say;
Далее компилятор делает то же самое, но оптимизатор понимает, что он не может даже найти ссылку на функцию где-либо. (Таким образом, оптимизатор вызывает сбой во время компиляции.)
bar 1;
Причина этой разницы с другими переменными состоит в том, что часто у вас может быть одна функция, которая полагается на другую, или вы хотите поместить функции после остальной части кода.
Кроме того, код функции обычно известен во время компиляции, тогда как значение переменной неизвестно до тех пор, пока она не будет назначена. (Назначение происходит во время выполнения.)
В основном, люди склонны использовать переменные и функции, поэтому они работают немного по-другому.
Нет необходимости требовать, чтобы они были объявлены перед использованием, поэтому ограничение было снято.
В Perl5 функции изменяют синтаксический анализатор на основе своего прототипа, поэтому компилятору необходимо увидеть объявление, прежде чем их использовать, чтобы он знал, как их нужно анализировать.
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 }
В Perl6 все функции компилируются так, как будто они принимают список, поэтому нет необходимости требовать, чтобы они были предварительно объявлены.
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 }