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

Определение

Давайте придерживаться определения Википедии

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

Майя Бритье придумала милый трюк, чтобы запомнить определение:

  • Простота
  • Удобство использования
  • Хороший код
  • Альтернатива
  • Читабельность

Но самое важное ключевое слово, которое нужно запомнить, — это производительность.

Если ваш код короче, его легче читать, писать и проверять, вы, наконец, более продуктивны… или нет. Давайте углубимся в это.

Что такое язык программирования?

Каждый «современный» язык программирования имеет две основные характеристики:

  • Тьюринг завершен: любая программа может быть смоделирована с помощью машины Тьюринга.
  • Без контекста: интерпретация оператора на языке не зависит от предыдущих операторов. Его можно описать формальной грамматикой.

Звучит сложно? Ну не так много.

Машина Тьюринга

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

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

Пример (на БЕЙСИКЕ)

10 PRINT "Hello, World!"

Инструкция — это «PRINT», которая печатает текст на консоли. а данные — это «Hello, World», хранящиеся где-то в памяти.

Грамматика без контекста

Формальная грамматика может быть представлена ​​как набор правил. А формальная грамматика не зависит от контекста, если всегда можно использовать один и тот же набор правил. Это становится сложно.

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

Например, возьмем слово может. Не могли бы вы сказать мне, это может быть существительным или глаголом в этом предложении? Ну это и то и другое одновременно как кот Шрёдингера.

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

Грамматика калькулятора в ANTLR (укороченная)

уравнение : выражение (EQ | GT | LT) выражение ;

выражение : multExpr ((ПЛЮС | ​​МИНУС) multExpr)* ;

multExp : powExpr ((TIMES | DIV) powExpr)* ;

powExpr : number (номер POW)* ;

Следующий текст: 17 = 5 + 4 *3 может быть обработан синтаксическим анализатором, реализующим эту грамматику, и сгенерирует следующее дерево синтаксического анализа:

Комплекс не так ли? Мы начинаем с 5 символов (17,=,5,+,4,*, 3) и заканчиваем 17 узлами.

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

В этом случае дерево будет выглядеть следующим образом:

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

Ну, используйте стек.

Вы начинаете со сложенных символов (терминалы и производства ) и на каждом шаге вы «уменьшаете» элементы в стеке.

Символическая программа выглядит так:

  • умножь 4 на 3 и вставь результат
  • добавить 5 к результату
  • проверить, что результат равен 17.

В более «языковом ассемблере» вы получаете:

POP
POP
ДОБАВИТЬ
POP
ДОБАВИТЬ
POP
ТЕСТ

Это именно то, что сделал ваш старый программируемый калькулятор HP, используя обратную польскую нотацию (RPN).

Вернемся к нашему синтаксическому сахару

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

В последнем примере при переходе от конкретного синтаксического дерева к абстрактному синтаксическому дереву мы удалили бесполезные узлы и заменили их более значимыми.

Но что, если вместо этого мы заменим один узел целым поддеревом?

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

Но есть предостережение: вы должны изменить свой компилятор (или интерпретатор).

Ну, один язык обошёл это: C.

Сделайте свой собственный синтаксический сахар

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

Так почему бы вместо этого не выполнить предварительную обработку кода, содержащего синтаксический сахар, и позволить генерировать код без синтаксического сахара? Именно так поступил препроцессор C/C++.

Примерно в 1973 году инженеры Bell Labs определили новый «язык», который можно было внедрить в обычный код C и «предварительно обработать», чтобы заменить его реальным кодом. Основными особенностями этого языка являются:

  • Включение содержимого внешнего файла: #include
  • Текстовое расширение значений: #define
  • Параметризованные макросы. Макрос раскрывается как обычный #define, но может содержать параметры, которые заменяются во время раскрытия макроса.
  • Условия: макросы предварительной обработки могут быть отключены или включены в зависимости от значения «переменных препроцессора».

Риск диабета и послевкусие

Почему препроцессор C не используется в Python, Java или JavaScript?

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

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

Главный недостаток препроцессора C заключается в том, что он выполняет текстовую замену. Препроцессор не знает о языке C. Он понятия не имеет, является ли сгенерированный код допустимым кодом C или нет.

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

Есть и другие проблемы с (нестандартным) синтаксическим сахаром:

  • Сложность языка: больше синтаксического сахара означает более сложный язык. Спецификация языка C++ более чем в 5 раз больше, чем спецификация языка C, но в 5 раз ли она лучше?
  • Скрытые побочные эффекты: не все функции синтаксического сахара полезны в каждом случае. Иногда такая конструкция ограничивает вас в плане гибкости. С конструкцией foreach вы не можете получить доступ к счетчику. Так как же построить путь из списка элементов пути без разделителя в конце пути?
  • Плохо известные конструкции. Конструкция, используемая в вашей программе всего несколько раз, скорее всего, будет плохо понята вами и рецензентами и, таким образом, может привести к ошибкам и усложнить рефакторинг кода.

Заключение

Синтаксический сахар имеет долгую историю. От умного трюка, облегчающего вам жизнь, до сложного набора функций (препроцессор C) — это еще один инструмент, который можно использовать как во благо, так и во зло.

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

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