Почему имена переменных не начинаются с цифр?

Я работал с новым разработчиком С++ некоторое время назад, когда он задал вопрос: "Почему имена переменных не начинаются с цифр?"

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

Был ли это правильный ответ? Есть ли еще причины?

string 2BeOrNot2Be = "that is the question"; // Why won't this compile?

Ответ 1

Потому что тогда строка цифр будет действительным идентификатором, а также действительным числом.

int 17 = 497;
int 42 = 6 * 9;
String 1111 = "Totally text";

Ответ 2

Хорошо подумайте об этом:

int 2d = 42;
double a = 2d;

Что такое? 2,0? или 42?

Подсказка, если вы ее не получили, d после числа означает число, перед которым он является двойным литералом

Ответ 3

Теперь это соглашение, но оно началось как техническое требование.

В старые времена синтаксические анализаторы языков, такие как FORTRAN или BASIC, не требовали использования пробелов. Итак, в основном, следующие идентичны:

10 V1=100
20 PRINT V1

и

10V1=100
20PRINTV1

Теперь предположим, что числовые префиксы разрешены. Как вы это понимаете?

101V=100

а

10 1V = 100

или

101 V = 100

или

1 01V = 100

Итак, это было сделано незаконным.

Ответ 4

Так как во время компиляции в лексическом анализе избегается обратное отслеживание. Переменная вроде:

Apple;

компилятор сразу узнает это идентификатор, когда он встретит букву "A".

Однако переменная типа:

123apple;
Компилятор

не сможет решить, будет ли это число или идентификатор, пока он не достигнет "a", и в результате ему потребуется откат.

Ответ 5

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

Языки, где пространство незначителен (например, ALGOL и оригинальный FORTRAN, если я правильно помню), не могли принимать номера, чтобы начинать идентификаторы по этой причине.

Это идет назад - перед специальными обозначениями для обозначения памяти или числовой базы.

Ответ 6

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

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

Также существуют стилистические значения, которые, как предполагается, являются мнемониками, поэтому слова гораздо легче запоминать, чем числа. Когда написано много оригинальных языков, устанавливающих стили в течение следующих нескольких десятилетий, они не думали о замене "2" на "to".

Ответ 7

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

Я думаю, что часть проблемы исходит от числовых литералов, таких как 0xdeadbeef, из-за чего трудно найти легко запоминаемые правила для идентификаторов, которые могут начинаться с цифры. Один из способов сделать это может заключаться в том, чтобы разрешить любое совпадение [A-Za-z _] +, которое НЕ является ключевым словом или числовым литералом. Проблема в том, что это привело бы к тому, что допустимы такие странные вещи, как 0xdeadpork, но не 0xdeadbeef. В конечном счете, я думаю, что мы должны быть справедливы ко всем мясам: P.

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

Ответ 8

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

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

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

Ответ 9

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

Тем не менее, почти все время, когда язык не позволяет именам переменных начинаться с чисел, это потому, что это правила языка. Часто это связано с тем, что такое простое правило значительно упрощает анализ и лексирование языка. Однако не все разработчики языка знают, что это настоящая причина. Современные инструменты лексики помогают, потому что, если вы попытаетесь определить ее как допустимую, они дадут вам разбор конфликтов.

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

Для примера довольно простого языка HTML-шаблонов, который позволяет переменным начинать с чисел и иметь встроенные пространства, посмотрите Qompose.

Ответ 10

Потому что, если вы разрешили ключевое слово и идентификатор начинать с числовых символов, лексер (часть компилятора) не мог легко различать начало числового литерала и ключевое слово, не получая намного сложнее (и медленнее).

Ответ 11

Ограничение произвольно. Различные Lispы разрешают имена символов начинаться с цифр.

Ответ 12

Имена переменных не могут начинаться с цифры, потому что это может вызвать некоторые проблемы, как показано ниже:

int a = 2;
int 2 = 5;
int c = 2 * a; 

каково значение c? 4, или 10!

другой пример:

float 5 = 25;
float b = 5.5;

является первым числом или является объектом (. operator) Аналогичная проблема возникает и во втором 5.

Возможно, есть и другие причины. Таким образом, мы не должны использовать какую-либо цифру в начале имени переменной.

Ответ 13

COBOL позволяет переменным начинать с цифры.

Ответ 14

С++ не может иметь этого, потому что разработчики языка сделали это правилом. Если бы вы создали свой собственный язык, вы наверняка позволили бы это, но вы, вероятно, столкнулись бы с теми же проблемами, что и они, и решили не допускать этого. Примеры имен переменных, которые могут вызвать проблемы:

0x, 2d, 5555

Ответ 15

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

Разве это не Dykstra сказал, что "самым важным аспектом любого инструмента является его влияние на пользователя"?

Ответ 16

Вероятно, потому, что человеку проще определить, является ли это числом или идентификатором, а также традицией. Идентификаторы, которые могут начинаться с цифры, не будут усложнять лексическое сканирование всего этого.

Не все языки имеют запрещенные идентификаторы, начинающиеся с цифры. В Forth они могут быть числами, а маленькие целые числа обычно определялись как слова Forth (по существу, идентификаторы), так как быстрее было читать "2" в качестве подпрограммы, чтобы нажимать 2 на стек, чем распознавать "2" в виде числа чье значение равно 2. (При обработке ввода от программиста или блока диска система Forth разделила вход в соответствии с пробелами. Он попытался бы найти токен в словаре, чтобы определить, было ли оно определенным словом, и если бы не попытался перевести его в число, а если бы не флаг ошибки.)

Ответ 17

Предположим, вы разрешили имена символов начинать с цифр. Теперь предположим, что вы хотите назвать переменную 12345 foobar. Как бы вы отделили это от 12345? На самом деле это не очень сложно сделать с регулярным выражением. Проблема на самом деле является одной из характеристик. Я не могу объяснить, почему это очень подробно, но, по сути, сводится к тому, что дифференциация 12345 foobar с 12345 требует возврата назад. Это делает регулярное выражение недетерминированным.

Там гораздо лучшее объяснение этого здесь.

Ответ 18

компилятор легко идентифицировать переменную, используя ASCII в памяти, а не в номере.

Ответ 19

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

Вопрос сродни тому, чтобы спросить, почему Король не может перемещать четыре места за раз в шахматы? Это потому, что в шахматах это незаконный ход. Может ли это в другой игре уверенно. Это зависит от правил игры.

Ответ 20

Первоначально это было просто потому, что легче запомнить (вы можете придать ему большее значение) имена переменных как строки, а не числа, хотя числа могут быть включены в строку, чтобы улучшить значение строки или разрешить использование одного и того же имя переменной, но имеет обозначение как отдельное, но близкое значение или контекст. Например, loop1, loop2 и т.д. Всегда сообщали бы вам, что вы были в цикле, и/или цикл 2 был циклом в loop1. Что бы вы предпочли (имеет большее значение) как переменную: адрес или 1121298? Что легче запомнить? Однако, если язык использует что-то, чтобы обозначить, что это не только текст или числа (например, $in $address), это действительно не должно иметь значения, поскольку это говорит компилятору, что следующее следует рассматривать как переменную ( в этом случае). В любом случае это сводится к тому, что разработчики языка хотят использовать в качестве правил для своего языка.

Ответ 21

Переменная может рассматриваться как значение и во время компиляции во время компиляции поэтому значение может вызывать значение снова и снова рекурсивно

Ответ 22

Отказоустойчивость исключается на этапе лексического анализа при компиляции фрагмента кода. Переменная, как Apple; , компилятор сразу узнает свой идентификатор, когда он встретит букву "A" на фазе лексического анализа. Однако переменная типа 123apple; , компилятор не сможет решить, будет ли его номер или идентификатор до тех пор, пока он не достигнет "а", и ему потребуется отступить, чтобы перейти на фазу лексического анализа, чтобы определить, что это переменная. Но он не поддерживается в компиляторе.

Справка

Ответ 23

Компилятор имеет 7 фаз следующим образом:

  1. Лексический анализ
  2. Анализ синтаксиса
  3. Семантический анализ
  4. Генерация промежуточного кода
  5. Оптимизация кода
  6. Генерация кода
  7. Таблица символов

Отказоустойчивость исключается на этапе лексического анализа при компиляции фрагмента кода. Переменная, подобная Apple, компилятор сразу узнает свой идентификатор, когда встречает букву "A" на фазе лексического анализа. Тем не менее, переменная типа 123apple, компилятор не сможет решить, будет ли ее число или идентификатор до тех пор, пока он не достигнет "а", и ему требуется обратное отслеживание, чтобы перейти на фазу лексического анализа, чтобы определить, что это переменная. Но он не поддерживается в компиляторе.

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

Ответ 24

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

пусть 1 = "Привет, мир!" печать (1) печать (1)

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