Сигилы облегчают чтение исходного кода?

13

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

Пример;

 var $foo = "something";
 echo $foo;

Я разрабатываю новый язык сценариев для бизнес-приложений, и у моих целевых пользователей нет опыта программирования. Эти символы облегчают чтение и использование кода?

Одна из причин, по которой PHP использует это, $заключается в том, что без него PHP не может определить, является ли имя ссылкой на функцию или ссылку на переменную. Это потому, что язык допускает странные ссылки на функции. Таким образом, $символ помогает анализатору разделить пространство имен.

У меня нет этой проблемы в моем парсере. Так что мой вопрос чисто о читабельности и простоте использования. Я столько лет программировал на PHP, что, когда я вижу, $fooмне легко определить это как переменную. Я просто отдаю предпочтение этому идентификатору?

Reactgular
источник
19
ИМО, код более читабелен без сигил
Джон Дворак
6
@JanDvorak +1 за то, что дал мне новое слово дня. Я попытаюсь использовать sigilsтри раза сегодня в разговорах.
Reactgular
6
IMO Это зависит от того, есть ли у вашего редактора подсветка синтаксиса.
CodeBeard
5
Если вы используете var $x = ...или type $x = ...тогда, я думаю, что $ излишне. Если бы вы только что $x = ...это сделали, это могло бы стоить сделать. Особенно, если вы не хотите поддерживать подсветку синтаксиса в обычных редакторах. Однако, как предпочтение, мне не нравитсяsigils
CodeBeard
5
сигилы похожи на принудительную венгерскую нотацию
чокнутый урод

Ответы:

13

Фактические технические возможности и ограничения не имеют ничего общего с тем, что предлагается в этой теме. Давайте сначала разберемся с ними.

Вот что $ делает возможным в PHP:

  • Переменные переменные
  • Переменные с ключевым словом например, $returnили возможность использовать одно и то же имя для переменной и функции / константы, например$__FILE__

Ограничения или функции, не связанные с префиксом $:

  • В противном случае реализация не сможет определить разницу между функциями и переменными
  • PHP строка интерполяции или шаблон синтаксиса
  • Обязательное объявление переменной

Это означает, что нет технической причины, по которой вы не могли бы

foo = "something";
echo foo;

или

foo = "something";
echo "foo = $foo";
//would print
//foo = something 

Однако вы не можете иметь (при условии, returnчто это ключевое слово)

return = "something";

Без серьезных осложнений. Если бы вы использовали такой префикс как $, то это не было бы проблемой.

Это мнение, но я полагаю, что сигил будет стоить того, чтобы не программисты, поскольку он позволяет им использовать ключевые слова в качестве имен переменных, для них это будет выглядеть как произвольное ограничение: P

Esailija
источник
О return = "something";, C # имеет «контекстные ключевые слова», что также стоит проверить при разработке языков.
luiscubal
1
@luiscubal пишет, что в C # неудивительно, что требуется сигил, поэтому, если вы хотите, чтобы этот код компилировался, вам нужно написать @return = "something;". Да, есть несколько контекстных ключевых слов, но сделать их все контекстными означало бы гораздо более сложную реализацию.
Esailija
7

Сигилы на самом деле имеют гораздо больше смысла в perl, где они обеспечивают определенную проверку типов. В php они мало помогают вне шаблонов. Вы можете почувствовать их полезность и читабельность, глядя на разные языки. Вряд ли их используют.

В языке, ориентированном на конечного пользователя, над которым я работаю, я даже иду дальше, делая идентификаторы нечувствительными к регистру и допуская пробелы и апострофы. Это позволяет мне делать такие имена переменных Karl's heightнамного ближе к естественным языкам.

Карл Билефельдт
источник
1
+1 для пробелов в переменных, но я понятия не имею, как это реализовать. Не уверен, что мне будет легче читать. Я просто не привык к этому.
Reactgular
1
Мне нравится эта идея. Но я бы не хотел писать синтаксический анализатор для языка с пробелами в идентификаторе. :-)At Karl's for the night = true;
Мартин Йорк
Но было бы интересно увидеть все эти стандарты, которые мы добавляем в начало языка, чтобы помочь нам его прочитать. Вместо того, чтобы проверяться вручную внешним инструментом, но становитесь частью определения языка. Таким образом, у нас не может быть бессмысленных аргументов об именах идентификаторов в стандартах кодирования (как они есть в языке).
Мартин Йорк,
2
Однако нечувствительность к регистру имеет проблему интернационализации. Если вы разрешаете символы из многих языков, вы можете столкнуться с именами, которые «одинаковы» в некоторых локалях, но не в других.
luiscubal
1
Разрешение пробелов в переменных в принципе не имеет большого значения - это просто означает грамматическое правило для идентификаторов, которое допускает использование нескольких слов. Однако это означает, что другие вещи могут быть невозможны в грамматике без создания двусмысленности. Например, в Хаскелеmap sum это частично примененный вызов функции - функция sumпередается в качестве параметра map. Но оба они являются просто именами библиотек, поэтому при наличии map sumмногословных идентификаторов компилятор не может знать, является ли один многословный идентификатор или приложение-функция, основанное на двух однословных идентификаторах.
Steve314
7

Несколько лет назад я выучил Applesoft Basic. К строкам всегда добавляется суффикс, $а к массивам - суффикс %. Вот как работает язык. Вы смотрели на что-то, вы знали, что это было. Я никогда не слишком углублялся в переводчика, чтобы понять, почему это так, или конструктивные решения, которые сделали это так.


Символ в php происходит от его perl-влияния (на которое повлияли awkи sh). Символ в Perl - это нечто большее, чем просто то, $что он может идентифицировать много разных типов:

  • $ скаляр
  • @ список
  • % гашиш
  • & кодоблок
  • * тип-глоб

Символ определяет, какую часть структуры таблицы символов вы просматриваете. За кулисами запись таблицы символов для foo (доступ через *foo- typeglob) содержит все, что может быть foo. Существует $foo, @foo,%foo , то формат foo , &foo, то указатель_на_файл Foo, и т.д ...

Это также позволяет создать псевдоним одной переменной для другой:

#!/usr/bin/perl

$foo = "foo";
@qux = (1,2);
*bar = \$foo;
*bar = \@qux;

print "$bar @bar\n";

Это печатает foo 1 2 - в Perl, это то, для чего на самом деле предназначены сигилы , не то, что вы должны это делать, а то, что есть нечто закулисное, что они делают.

В сигилах не так много для удобства чтения, а так , что один может иметь $fooи@foo без столкновения в пространстве имен (сравните другие языки, где нельзя иметь оба int foo; int[] foo;)


Символы читабельности - это то, что изучается как часть любого языка - чтение синтаксиса. Гипотетически, вы можете принудить сам тип (как венгерская нотация) быть частью идентификатора.

Что-то в лекс по линии:

typeChar  [is]
capLetter [A-Z]
letter    [a-z]
digit     [0-9]
%%
{typeChar}{capLetter}(letter}|{digit})* { prientif("iddentifier");}
%%

И тогда вы могли бы иметь такой код

iFoo = 42;
sFoo = "a string";
iBar = iFoo * 2;

Я не говорю, что это хорошая идея, а скорее, что тот, кто привык к языку, сможет читать его по-родному и думать, что он улучшает читабельность, в то время как тот, кто не знаком с языком, может подумать, что он просто добавляет куча шума для языка.

Однако, после работы с языком, определенным таким образом, я, вероятно, мог прочитать его без проблем.

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

Можно создать новый язык для непрограммистов, использующих сигилы, и любой, кто никогда не программировал раньше, никогда не будет жаловаться на них. С другой стороны, вы не могли бы использовать их как часть языка, и тогда бы программисты ruby ​​или perl жаловались на то, что они упускают какую-то ключевую информацию.

Это действительно не имеет значения. Что важно, так это то, как сигилы будут вписываться в язык, если вы их используете или нет. Вы хотите быть в состоянии сделать "123 $foo 456"или вы должны сделать "123 " + foo + " 456"? Это где решение должно быть принято.


источник
1
Строковая интерполяция, такая как "123 $foo 456", не включена префиксом сигилы и является полностью ортогональной к нему.
Esailija
1
Его часть интерполяции переменных и зависит от того, как анализируется строка. Сигилы могут сделать это проще (это можно сделать другими способами, как показано в « Лучшем способе выполнения интерполяции переменных в javascript», но это не является частью основного языка. Сигилы, возможно, облегчают написание и понимание этого.
1
@MichaelT Нет, тот факт, что переменные имеют префиксы, не делает реализацию интерполяции строк проще или сложнее. Это просто две совершенно не связанные вещи. Для читателя, возможно, было бы хорошим выбором использовать $asdсинтаксис строковой интерполяции, если $он уже использовался для префиксов переменных, но это не имело ничего общего с реальной возможностью реализации интерполяции строк.
Esailija
2
@Esailija не могли бы вы описать, как они не связаны? Кроме того, en.wikipedia.org/wiki/Variable_interpolation - «Языки, которые поддерживают интерполяцию переменных, включают Perl, PHP, Ruby, Tcl, Groovy и большинство оболочек Unix. В этих языках интерполяция переменных происходит только тогда, когда строковый литерал двойные кавычки, но не в одинарных кавычках. Переменные распознаются, потому что в этих языках переменные начинаются с символа (обычно "$"). "
@MichaelT Символ доллара, используемый в префиксах переменных и интерполяции строк, является совершенно поверхностным выбором (который имеет только аргументы читабельности, не имеет ничего общего с реализацией, он может также быть, #который используется в coffeescript, например. И coffeescript не имеет префикса переменные с #- на самом деле это вообще не префикс переменных)
Esailija
3

Я не согласен с тем, что PHP использует $ для отличия переменных от funcs. Хотя бы потому, что в PHP есть C-подобный синтаксис, а у funcs () есть имена после имени.

Прочитайте этот пост о переполнении стека о том, почему $ в PHP.

Многие популярные языки, такие как C, C ++, C #, Java не используют $, и мы можем легко отличить var от функции.

В PHP $ помогает, например, когда вы пишете: echo "var = $ var"

Без этого такой трюк будет невозможен.

Руслан Засухин
источник
+1 ах, это имеет больше смысла. Благодарю.
Reactgular
3
Язык с символами не имеет ничего общего с интерполяцией строк, как в вашем примереecho "var = $var"
4
-1. Причуды синтаксиса PHP не из-за некоторых реальных ограничений, а потому, что правила грамматики очень плохо разработаны, если разработаны вообще. Вот почему им нужны хаки, чтобы включить их fn()[]с разумной грамматикой, которая бы работала из коробки, даже не задумываясь об этом.
Esailija
@svidgen Да. Вы не можете безопасно выполнять интерполяцию строк без какого-либо способа указать, какая часть строки должна отображаться в переменную. Другие языки заканчиваются тем, что я считаю раздражающим / ненужным многословием, таким как форматирование строк Python. Тем не менее, в PHP есть и другие преимущества: Руслан Засухин неверно говорит, что функции всегда будут обозначаться паренами, так как их также можно передавать в виде ссылок.
Изката
@Izkata То, как вы используете переменные в языке, не имеет ничего общего с синтаксисом интерполяции строк. Но это подразумевалось в этом ответе, следовательно, -1 ...
Esailija
3

После всех этих ответов я хочу дать еще несколько очков Мэтью Фоскарини.

  • Вы рассматриваете проблему сейчас как «конструктор языка». Вы пытаетесь понять, почему другой язык имеет ту или иную функцию, чтобы выбрать, если использовать что-то на вашем родном языке. Я нахожусь в том же положении много лет, потому что разрабатываю парсер SQL для нашей базы данных Valentina.
  • Я советую вам взглянуть на antlr.org и даже прочитать книгу от Теренса. В нем много хороших вещей для разработчиков языка.
  • Я до сих пор не согласен с «причинами», раскрытыми другими ответами. Они предполагают, что автор PHP в своей голове решил использовать $, чтобы иметь возможность использовать зарезервированные ключевые слова и лучше отличать переменные от не-переменных. Я так не считаю ... хотя доказать можно только свою собственную историю.
  • Скорее всего, они просто следуют Perl и более ранним языкам. Как подчеркивает Терренс, большинство языков схожи, особенно в части LEXER. И обычно конструктор нового языка может просто выбрать, какой язык он собирается развивать, и затем взять лексер этой языковой грамматики. И это то, что вы должны сделать сейчас. Не нужно изобретать с нуля. Бьюсь об заклад, то же самое сделали авторы PHP.
  • Все остальное, что люди упоминают:
    • отличать переменные от не переменных
    • резервные слова как имена переменных
    • возможность разместить переменную внутри строки
    • может быть еще (я не большой специалист по PHP)

являются побочными эффектами этого LEXER , потому что он способен распознавать токен.

Возьмем для примера: в SQL мы используем «», чтобы иметь возможность использовать идентификаторы с зарезервированными словами и даже идентификаторы с пробелами «Имя», «Имя группы». GROUP является ключевым словом. Была проблема - было специальное решение.

PS Очень хороший комментарий от MichaelT.

Руслан Засухин
источник
+1 спасибо за отличную ссылку. В итоге я воспользовался этим, но ваша ссылка выглядит намного лучше. goldparser.org
Reactgular
Спасибо также за вашу ссылку. Я не видел этот анализатор золота раньше. Выглядит также интересно.
Руслан Засухин
@RuslanZasukhin Если вы делаете ссылку на мой ответ, я никогда не говорил, что разработчик намеревался включить ключевые слова. Я только сказал, что использование ключевых слов в качестве имен переменных становится технически возможным, когда переменные имеют префикс с таким символом, как $. Также «возможность размещать переменную внутри строки» не из-за того, что переменные имеют префикс с таким символом, как $. То есть "123 $foo 456"будет работать, даже если синтаксис переменной похож на foo = 3или @foo = 3. Они не связаны друг с другом.
Esailija
3

... сигил позволяет:

  • Лучше отличать переменные от не переменных . Люди, которые все еще изучают основные понятия, могут столкнуться с трудностями при определении того, какие слова являются переменными, а какие нет. Они часто начинают с чтения примеров или чужого кода без достаточного фона.

  • Используйте зарезервированные ключевые слова или имена функций в качестве имен переменных . Иногда я обнаруживал, что некоторые из этих имен являются правильными для переменной (то есть, $countкогда была определена count()функция), и благодарил сигил за предоставленную мне возможность использовать их.

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

$isdir=isdir($dir);

if(/* complex condition implying $isdir */) {
/* etc */
}

Zjr
источник
1
ZHR, что значит лучше? В C ++ мы пишем все наши переменные без $ и отлично и легко их различаем. Пример: {int z = 0; z = 55; г (г); } И в C ++ мы также можем использовать имя функции, если нужно назначить, например указатель на функцию.
Руслан Засухин
@RuslanZasukhin, компьютерные неграмотные, знаете ли вы? Попробуйте научить их C ++, вы будете поражены.
ZJR
Кроме того: я не думаю, что сигил всегда должен быть $знаком. Я помню, как знак доллара смущал меня, когда я был ребенком, из-за присущей ему денежной ассоциации. %может быть реальной альтернативой.
ZJR