JJ и Мориц предоставили полезные ответы.
Этот нансвер представляет собой еще один шарик воска. За последние несколько дней я написал и отклонил несколько ответов на ваш вопрос. Ни один не был очень полезен. Я не уверен, что это так, но я решил, что наконец-то получил первую версию чего-то, что стоит опубликовать, независимо от ее текущей полезности.
В этом первом выпуске мой ответ - всего лишь серия замечаний и вопросов. Я также надеюсь добавить объяснение моих наблюдений, основанное на том, что я получил от написания кода компилятора, чтобы понять то, что мы видим. (Сейчас я только что записал начало этого процесса как вторую половину этого ответа.)
Различия (если есть) между Package::<&var>
против &Package::var
?
Это принципиально другой синтаксис. Они не полностью взаимозаменяемы там, где вы можете их написать. Они приводят к различным оценкам. Их результатом могут быть разные вещи.
Давайте пройдемся по множеству вариаций, вытянув различия.
say Package::<&var>; # compile-time error: Undeclared name: Package
Итак, на секунду забудьте о бите ::<...>
. P6 смотрит на этот Package
бит и требует, чтобы это было уже объявленное имя. Это кажется достаточно простым.
say &Package::var; # (Any)
Разница! По какой-то причине в этом втором синтаксисе у P6 нет проблем с тем, что эти два произвольных имени (Package
и var
) не были объявлены. Кто знает, что он делает с &
. И почему это (Any)
а не (Callable)
или Nil
?
Давайте попробуем объявить эти вещи. Во-первых:
my Package::<&var> = { 42 } # compile-time error: Type 'Package' is not declared
OK. Но если мы объявим Package
, то ничего не улучшится:
package Package {}
my Package::<&var> = { 42 } # compile-time error: Malformed my
ОК, начните снова с чистого листа, без объявления package
. А как насчет другого синтаксиса?:
my &Package::var = { 42 }
Yay. P6 принимает этот код. Теперь для следующих нескольких строк мы примем объявление выше. Как насчет:
say &Package::var(); # 42
\ o / Так можем ли мы использовать другой синтаксис?:
say Package::<&var>(); # compile-time error: Undeclared name: Package
Неа. Кажется, что my
не объявил Package
с &var
в нем. Может быть, он объявил &Package::var
, где ::
просто является частью имени, но не о пакетах? P6 поддерживает набор «псевдо» пакетов . Один из них LEXICAL
:
say LEXICAL::; # PseudoStash.new(... &Package::var => (Callable) ...
Бинго. Или это так?
say LEXICAL::<&Package::var>(); # Cannot invoke this object
# (REPR: Uninstantiable; Callable)
Что случилось с нашим { 42 }
?
Хм. Давайте начнем с чистого листа и создадим &Package::var
совершенно другим способом:
package Package { our sub var { 99 } }
say &Package::var(); # 99
say Package::<&var>(); # 99
Ничего себе. Теперь, предполагая те строки выше и пытаясь добавить больше:
my Package::<&var> = { 42 } # Compile-time error: Malformed my
Этого следовало ожидать, учитывая нашу предыдущую попытку выше. Как насчет:
my &Package::var = { 42 } # Cannot modify an immutable Sub (&var)
Теперь все имеет смысл? ;)
Правописание кода компилятора, проверка грамматики
1 Я потратил много времени, пытаясь понять, в чем дело на самом деле , прежде чем смотреть на исходный код компилятора Rakudo . Это сноска, покрывающая мое начальное написание компилятора. Я надеюсь продолжить это завтра и превратить этот ответ в ответ на этих выходных.
Хорошая новость в том, что это просто код P6 - большая часть Rakudo написана на P6.
Плохая новость - знать, где искать. Вы можете увидеть каталог doc
, а затем обзор компилятора . Но тогда вы заметите, что обзорный документ почти не затрагивался с 2010 года! Не беспокойся Возможно посты Андрея Шитова помогут вам сориентироваться? Идем дальше ...
В данном случае меня интересует понимание точной природы синтаксиса Package::<&var>
и &Package::var
. Когда я набираю «синтаксис» в поле поиска репозитория GH, в списке появляется второй файл Грамматика Perl 6 . Бинго.
Теперь приходят ужасные новости. Файл грамматики Perl 6 имеет 6K LOC и выглядит очень пугающим. Но я считаю, что все это имеет смысл, когда я хладнокровен.
Далее мне интересно, что искать на странице. ::
сетей 600+ матчей. Хм. ::<
- это всего лишь 1, но это сообщение об ошибке. А в чем? В token morename
. Глядя на это, я вижу, что это не актуально. Но '::'
около начала токена - это просто билет. Поиск по странице '::'
дает 10 совпадений. Первые 4 (от начала файла) - больше сообщений об ошибках. Следующие два находятся в указанном выше morename
токене. Осталось 4 матча.
Следующий появляется четверть через token term:sym<name>
. Имя". .oO (Undeclared name: Package
Так может это актуально?)
Далее token typename
. «Типовое имя». .oO (Type 'Package' is not declared
Так может это тоже актуально?)
token methodop
. Определенно не актуально.
Наконец token infix:sym<?? !!>
. Нет.