Есть ли цель или выгода в том, чтобы запретить повторное связывание переменных без сигилов? - PullRequest
0 голосов
/ 17 мая 2018

Пытаясь лучше понять переменные без сигил и чем они отличаются от переменных $, я обнаружил, что, в отличие от $ переменных с сигилами, переменные без сигилов не могут быть восстановлены после их инициализации:

my $a = 42;
my $b := $a;
$b := 42;       # No exception generated

my \c := $a;
c := 42;        # OUTPUT: «Cannot use bind operator with this left-hand side␤»

Это задумано? Если да, то есть ли цель или выгода запретить повторное связывание переменных без сигилов, когда $ переменных сигилов не запрещено делать это?

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Да, это, конечно, дизайн, и - как и большинство вещей в дизайне Perl (6) - это так по нескольким причинам.

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

  • Синтаксическая неоднозначность (вы можете вызывать переменную как угодно, даже если есть ключевое слово с таким именем)
  • Удобочитаемость (данные в программе выдаются благодаря символу)
  • Определение семантики присваивания (в Perl 6 присвоение означает «копировать в», поэтому my @a = @b означает итерацию @b и помещает каждую вещь в нее в @a, таким образом, любые будущие присвоения @b не будут влиять @a)
  • Ограничение того, что там может быть связано (например, только Positional вещей @)
  • В случае $, управление тем, что будет считаться отдельным элементом
  • В случае @ для параметра подписи, вызывающего кэширование входящего Seq

Таким образом, каждый сигил содержит набор полезных поведений по умолчанию для данных, которые следует рассматривать как отдельный элемент ($), что-то для индексации в позиционном (@), что-то для индексации с помощью ключ (%) и что-то, что можно назвать (&). Каждый из них, как в контексте назначения, низкоуровневого связывания, так и связывания подписи, несет обычно желательную семантику для данных такого типа.

Это нормально, пока кто-то не захочет написать код, который будет полиморфным для всех этих поведений, или не будет придерживаться какого-либо поведения сигилов. Более ранние итерации дизайна языка Perl 6 имели что-то вроде sub foo($x is parcel) { }, где вещь is parcel фактически означала «не накладывать на нее никакой семантики сигил-ий», за исключением того, что это было довольно запутанным, потому что вещь имела $ сигил, но был исключен из семантики. Было понято, что если бы поведение sigil не применялось, то было бы лучше, если бы оно выглядело иначе (принцип дизайна «разные вещи должны выглядеть по-разному», который также часто появляется в Perl). Самый очевидный способ выглядеть по-другому - это не иметь сигилу.

Однако по синтаксическим соображениям в сигнатуре нужно было что-то для устранения неоднозначности имени, вводимого из типа (так как сигнатура типа (Foo) соответствует типу Foo, но игнорирует значение, которое уже поддерживается, и полезно и мы не хотели потерять это). \ был выбран, чтобы сыграть эту роль, получив sub foo(\x) { }, что затем позволило использовать x внутри подпрограммы.

Насколько я помню, разрешение этой формы в случае my появилось чуть позже, хотя я не совсем уверен в этом. Одна из важных особенностей символа без сигил, не связанного с поведением, заключается в том, что он также не фиксирует поведение assignment , поэтому = на нем немного более поздний (если это возможно) компилятор рассматривает сигил и выдает совершенно другой код для назначений $ / & и @ / %). Конечно, если символ привязан к значению, тогда присвоение невозможно.

Это оставляет вопрос обязательного поведения. Было решено превратить символ без сигилы в синтаксис «статического одиночного назначения», как объяснено в одном из других ответов. Для этого были разные причины, в том числе:

  • Помощь в сохранении свойства читабельности сигил «данных выделяется», по крайней мере, следя за тем, чтобы все, что должно быть (немедленно) изменяемым, все еще содержало сигилу
  • Также улучшается читаемость программы благодаря наличию формы, которая позволяет читателю знать, что символ никогда не будет возвращен к новому значению, поэтому можно эффективно считать его постоянным в пределах области видимости. Это согласуется с тем, что легко объявить реальные constant s без сигил.
  • Осторожно поощряя более функциональный стиль (возможно, заставляя тех, кто решает, что они ненавидят сигил, платить остальным из нас код, который, по крайней мере, более читабелен иным способом, чем предлагают сигилы: -))

Наконец, я отмечу, что нахожу термин «переменная без сигилла» немного вводящим в заблуждение, потому что в нем нет ничего переменного.Это синтаксис для введения символа, который инициализируется привязанным к определенной вещи и всегда будет в течение (лексического) времени жизни этого символа.Лучший способ думать о них, вероятно, считать их отличными от переменных - которые подразумевают хранение - и вместо этого просто рассматривать их как способ присвоения имени значению.

0 голосов
/ 17 мая 2018

Переменные без сигилов имеют Одиночное статическое назначение семантика.

Преимущества возможности оптимизации

Цитирование из раздела «Преимущества» на вышеуказанной связанной странице SSA :

Основная полезность SSA заключается в том, что он одновременно упрощает и улучшает результаты различных оптимизаций компилятора, упрощая свойства переменных. Например, рассмотрим этот кусок кода:

y := 1
y := 2
x := y

Люди могут видеть, что первое назначение не является необходимым, и что значение y, используемое в третьей строке, происходит от второго назначения y. Чтобы определить это, программа должна выполнить анализ достигнутого определения. Но если программа в форме SSA, оба они незамедлительны:

y1 := 1
y2 := 2
x1 := y2

Алгоритмы оптимизации компилятора, которые либо активируются, либо сильно улучшаются с помощью SSA, включают [длинный список доступных оптимизаций].

Таким образом, в принципе, при написании кода с использованием переменных без сигиллов, вы предоставляете компилятору больше возможностей для оптимизации.

Преимущества человеческого рассуждения

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

(По этой причине я склонен думать, что привязка переменной без сигил к контейнеру, как я показал в своем комментарии к вашему вопросу, особенно к контейнеру Scalar, является сомнительной практикой.)

...