Висящая тема (или любая другая) переменная не перестает работать - PullRequest
5 голосов
/ 29 июня 2019

Это работает:

$_ =

say "hi";

То есть вы можете поместить любое количество пробелов между заданием и тем, что позади, оно просто проигнорирует его. Вы также можете использовать любую переменную (с my). Фактически, $ _ будет присвоен результат say, который равен True.

Это удивительно, но соответствует спецификации или просто удивительно?

Ответы [ 2 ]

8 голосов
/ 29 июня 2019

Может быть любое количество пробелов по обе стороны от оператора. Таким образом:

say 1
    + 2

    + 3;

Насколько компилятор видит это, полностью так же, как:

say 1 + 2 + 3;

Назначение (=) - просто еще один оператор, поэтому также следует этим правилам.

Далее, say - это просто обычная встроенная подпрограмма, поэтому она выглядит так:

my $answer = flip '24';
say $answer; # 42

Кроме дополнительных пробелов:

my $answer = 

    flip '24';
say $answer; # 42

В Perl 6 есть несколько мест, где пробел является значительным, но пробел между инфиксными операторами не является одним из них.

4 голосов
/ 29 июня 2019

TL; DR Синтаксис P6 - произвольная форма.

переменная висящей темы (или любой другой) не завершается

Проблема, которую вы описываете, носит очень общий характер. Это определенно не просто объявление / присваивание переменной!

В P6 синтаксический анализ оператора - единственной императивной единицы («сделай это») - обычно просто продолжается до тех пор, пока не достигнет явного разделителя операторов - ; - который приводит к завершению оператора точно так же, как точка (точная точка остановки) в конце этого английского предложения.

Вы можете поставить любое количество пробелов

Как и многие языки программирования, стандарт P6 обычно произвольной формы . То есть, где некоторые пробелы действительны, тогда обычно любое количество пробелов - горизонтальные и вертикальные пробелы - синтаксически эквивалентны.

$_ =

say "hi";

Вышеописанное работает точно так, как и следовало ожидать, если кто-то применяет принцип произвольной формы - это единственный оператор, присваивающий значение say переменной $_.

Это удивительно, но соответствует спецификации или просто удивительно?

Мне нравится изобретать (надеюсь, содержательные) изречения. Я только что изобрел «Сюрприз следует за догадкой».

Это зависит от спецификации. Я знаю, что ожидать этого. Меня это не удивляет.

Если кто-то принимает тот факт, что P6 обычно произвольная форма и имеет разделение точек с запятой , тогда, я предсказываю, (в конечном итоге - скорее всего, быстро) перестанут удивлять.


Вышесказанное является прямым ответом на ваш вопрос. Смотрите также ответ Джонатана, чтобы узнать больше о том же. Не стесняйтесь игнорировать остальную часть этого ответа.

В остальной части этого ответа я использую «произвольную форму» для обозначения комбинации синтаксиса произвольной формы P6, разделения операторов точки с запятой и блоков в скобках ({...}).

Остальная часть этого ответа состоит из трех разделов:

  • P6 исключения для синтаксиса произвольной формы

  • Свободная форма и ориентированная на линию

  • Свободная форма и с ориентацией на линии?

P6 исключения для синтаксиса произвольной формы

@ Ларри пришел к выводу, что интуиция, эстетика, удобство и / или другие факторы в некоторых случаях оправдывали исключение из чистого синтаксиса произвольной формы в стандарте P6.

Заявления могут опускать конечную точку с запятой, если они:

  • являются последним оператором в исходном файле или в блоке;

  • Конец в блоке, за закрытием которого стоит новая строка (игнорируя комментарии).

Таким образом, ни одно из трех утверждений ниже (if и два say s) не нуждается в закрывающей точке с запятой:

if 42 {
  say 'no semicolon needed before the closing curly'
}    # no semicolon needed after the closing curly
say   'no semicolon needed if last statement in source file'

Иногда это может быть не то, что нужно:

{ ... }   # the closing } ends the statement (block)
.()       # call is invoked on $_

Один из способов изменить это использовать круглые скобки:

({ ... })
.()       # calls the block on prior line

Для некоторых конструкций пробелы либо обязательны, либо запрещены. Например, некоторые постфиксы должны следовать непосредственно за значениями, к которым они применяются, а некоторые - не должны. Это синтаксические ошибки:

foo ++
foo«+»bar

Freeform против линии ориентированной

Для некоторых сценариев кодирования синтаксис произвольной формы P6, возможно, является сильным чистым положительным результатом, например:

  • Один вкладыш может использовать блоки;

  • FP-код является естественным (можно писать нетривиальные замыкания);

  • Более простое редактирование / рефакторинг / копирование / вставка.

Но есть и недостатки:

  • Затраты на запись и чтение синтаксиса произвольной формы - точки с запятой и фигурные скобки.

  • Игнорирование интуиции, которая, по-видимому, побудила вас опубликовать свой вопрос.

Последний является мощным. Все следующее может заставить кого-то думать, что say в вашем примере является частью нового оператора, который не является продолжением оператора $_ =:

  • Новая строка после =;

  • Пустая строка после этого;

  • Отсутствие отступа в начале строки say относительно строки $_ =;

  • Природа say (может показаться, что say должно быть началом нового оператора).

Результатом вышеприведенной интуиции является то, что некоторые языки программирования используют «линейно-ориентированный» синтаксис , а не произвольный, наиболее известным из которых является Python. 1

Свободная форма и строчно-ориентированный синтаксис

Некоторые языки, например, Haskell, допускают использование либо строкового или синтаксиса произвольной формы (по крайней мере, для некоторых языковых конструкций).

P6 поддерживает сленги , пользовательские модули, которые изменяют язык. Представьте себе сленг, который поддерживает как линейно-ориентированный код произвольной формы , так и , так:

  • Те, кто изучал P6, столкнулись с большим количеством знакомств и меньше сюрпризов, поскольку они изучили основы языка, сосредоточившись на либо линейно-ориентированном или коде произвольной формы, основанном на их предпочтениях;

  • Те, кто знаком с P6, могли бы написать лучший код, используя или линейно-ориентированный или синтаксис произвольной формы.

С риском усложнения вещей, представьте себе сленг, который принимает не только ориентацию линии, но также правило вне игры , которое поддерживает Python, и реализует no strict; для нетипизированных переменных без сигил ( который сбрасывает деклараторы и сигилы и способствует неизменности). Вот фрагмент кода, написанного на воображаемом сленге, который я опубликовал в комментарии Reddit несколько недель назад:

sub egg(bar)
  put bar

data = ["Iron man", "is", "Tony Stark"]
callbacks = []

Возможно, что-то похожее на вышесказанное слишком сложно осуществить? (Я сейчас не понимаю, почему.)

Сноска

1 В оставшейся части этого раздела сравниваются P6 и Python, используя раздел Википедии о Операторы языка программирования в качестве руководства:

Разделитель операторов используется для разграничения границ между двумя отдельными операторами.

В P6 это ; или конец блоков.

В Python ; доступно для отдельных операторов. Но в первую очередь это ориентировано на линию.

Языки, которые интерпретируют конец строки как конец оператора, называются "ориентированными на строки" языками.

В Python конец строки завершает оператор, если только следующая строка не имеет соответствующего отступа (в этом случае это начало соответствующего субблока) или если в конце строки не появляется явный символ продолжения строки.

P6 не ориентирован на строку. (По крайней мере, не стандартный P6. Я поставлю сленг P6 в конце этого ответа, который поддерживает как произвольную, так и линейно-ориентированный синтаксис.)

«Продолжение строки» - это соглашение в линейно-ориентированных языках [которое] позволяет одному выражению занимать более одной строки.

Python имеет функции продолжения строки; см. статью в Википедии.

Стандартный P6 также имеет функции продолжения строки, несмотря на то, что он не ориентирован на линию. 2

2 P6 поддерживает продолжение линии. Продолжая цитаты из Википедии:

символ новой строки обычно приводит к добавлению токена в поток токенов, если не обнаружено продолжение строки.

(Токен - это наименьший фрагмент кода - помимо отдельного символа - он обрабатывается синтаксическим анализатором как атомарная единица.)

Стандарт P6 всегда предполагает разрыв токена, если он встречает символ новой строки, за исключением единственной строки, записанной в виде строк:

say
'The
 quick
 fox';

Это скомпилирует OK и отобразит The, quick и fox в трех отдельных строках.

Эквивалент в Python сгенерирует синтаксическую ошибку.

Обратная косая черта как последний символ строки

В P6 обратный слеш:

  • Не может появляться в середине токена;

  • Может использоваться для ввода пробела в исходном коде, который игнорируется синтаксическим анализатором во избежание синтаксической ошибки. Например:

        say @foo\
            »++
  • На самом деле это более общая концепция "unspace" , которую можно использовать в любом месте строки, а не только в конце:
        say @foo\            »++

Некоторая форма встроенного комментария служит продолжением строки

Это работает:

say {;}#`( An embedded
comment ).signature

Встроенный комментарий:

  • Не может появляться в середине токена;

  • Не такой общий, как обратная косая черта (say @foo#`[...]»++ не работает).

...