Синтаксический сахар
В статье не хватает ссылок на источники (см. рекомендации по поиску). |
Синтаксический сахар (англ. syntactic sugar) — термин, обозначающий дополнения синтаксиса языка программирования, которые не добавляют новых возможностей, а делают использование языка более удобным для человека.
Определение
«Синтаксический сахар» — это любой элемент синтаксиса языка программирования, который даёт программисту альтернативный способ записи другой, уже имеющейся в языке синтаксической конструкции, и при этом является более удобным, или более кратким, или похожим на другой распространённый способ записи, или помогает писать программы в хорошем стиле. С формальной точки зрения синтаксический сахар ничего не меняет и выразительности языку не прибавляет, однако может заметно облегчить программисту описание некоторых операций. Одновременно синтаксический сахар, особенно при его неумеренном применении, может ухудшать читаемость кода и усложнять его поддержку. Конструкции, являющиеся синтаксическим сахаром, могут легко транслироваться в конструкции основного синтаксиса.
Необходимо отметить, что понятие синтаксического сахара во многом условно. Его использование предполагает, что из всего множества синтаксических конструкций можно выделить некоторый «базовый набор», обеспечивающий всю функциональность языка, и тогда дополнительные синтаксические средства, которые при желании можно выразить с помощью базового набора, и будут для данного языка синтаксическим сахаром. Однако многие конструкции являются взаимозаменяемыми, и далеко не всегда можно определённо сказать, какие именно из них являются базовыми, а какие — дополнительными. Например, в языке Модула-2 есть четыре вида циклов: цикл с предусловием, цикл с постусловием, цикл с шагом и безусловный цикл. Теоретически, первые три вида циклов могут быть легко выражены через последний. Являются ли они, в таком случае, синтаксическим сахаром? Обычно так не говорят, хотя формально под вышеприведённое определение они попадают.
Примеры
Сокращённые операторы
В языке Си и его потомках (C++, Java, C# и другие), а также во многих других, имеется отдельный синтаксис для операций увеличения, уменьшения и упрощённого присваивания:
- Увеличение и уменьшение
- унарные операторы
++
и--
обеспечивают, соответственно, увеличение и уменьшение значения переменной на единицу. Оба оператора имеют две формы — префиксную и постфиксную. В префиксной форме выражение имеет значение, соответствующее новому значению переменной, в постфиксной — старому.
int x = 10;
int y = 10;
a = x++; // постфиксная форма - эквивалентно a = x , x = x + 1;
b = --y; // префиксная форма - эквивалентно y = y - 1, b = y;
- Сокращённое присваивание
- для выражений вида «<переменная> = <переменная> <знак операции> <значение>» введена сокращённая форма записи «<переменная> <знак операции>= <значение>»:
int x = 10;
int y = 10;
x += 10; // эквивалентно x = x + 10;
y -= 5; // эквивалентно y = y - 5;
y *= x; // эквивалентно y = y * x;
x /= y; // эквивалентно x = x / y;
и т. д.
Сокращённые операторы были введены в Си из соображений эффективности — в машинном коде компьютера PDP-11, для которого и разрабатывался язык, существовали отдельные команды INC x
и DEC x
(«увеличить на 1» и «уменьшить на 1», соответственно), более короткие и быстрые, чем ADD #1,x
и SUB #1,x
; компилятор языка Си превращал ++
и --
именно в эти команды. В настоящее время язык Си используется на огромном количестве различных вычислительных платформ, у которых такие «сокращённые» команды либо не дают ощутимого выигрыша, либо вовсе отсутствуют; с другой стороны, оптимизирующие компиляторы умеют выявлять возможности сокращения кода и генерируют абсолютно одинаковый код как для x++
, так и для x = x + 1
, так что сокращённые команды превратились в самый настоящий синтаксический сахар.
Массивы в Си
Массивы в Си представляют собой блоки в памяти. Доступ к элементам массива производится через указатель на начало блока памяти (то есть, на начало массива) и смещение элемента относительно начального адреса. Это может быть записано без использования специального синтаксиса для массивов (a
— указатель на начало массива, i
— индекс необходимого элемента): *(a + i)
, но непосредственные операции с адресами в памяти и смещениями являются большим источником ошибок программистов, поэтому язык предоставляет специальный синтаксис: a[i]
. Кроме того, есть возможность обратиться к i
-му элементу массива уж совсем экзотическим способом: i[a]
, что аналогично a[i]
, так как значение указателя i+a
, очевидно, равно a+i
.
Тернарная операция в Си
Другой известный пример специализированной языковой конструкции — тернарная условная операция языка Си ?:
. Следующие два фрагмента кода делают одно и тоже:
int fn();
int a = 1;
int b;
if (a > 0)
b = fn(1);
else
b = fn(2);
int fn();
int a = 1;
int b = fn((a > 0)? 1 : 2);
Причина введения такой операции — желание вставлять проверку простых условий прямо в выражения и возможность прямо указать компилятору, что результатом проверки условия будет единственное значение. Конструкция действительно сокращает запись, но вот по поводу её удобства мнения могут быть разными. Многие считают, что сокращение записи в данном случае не окупает ухудшение читаемости кода.
Переопределение операторов
К синтаксическому сахару можно отнести и переопределение операторов, поддерживаемое многими языками программирования. В принципе, любая операция может быть оформлена как процедура (функция, метод). Переопределение операторов позволяет выполнять операции, созданные программистом, внешне так же, как и встроенные в язык.
Свойства
Ещё одним примером синтаксического сахара является концепция «свойств», поддерживаемая многими современными языками программирования. Имеется в виду объявление в классе псевдополей, которые внешне ведут себя как поля класса (имеют имя, тип, допускают присваивание и чтение), но в действительности таковыми не являются. Каждое обращение к свойству преобразуется компилятором в вызов метода доступа. Свойства совершенно не являются необходимыми (методы доступа можно вызывать и непосредственно) и используются исключительно для удобства, поскольку код с использованием свойств выглядит несколько проще и понятнее.
Критика
Не все программисты считают наличие синтаксического сахара в языках программирования и использование его программистами благом. Известна точка зрения Никлауса Вирта, которую разделяет часть программистского сообщества: согласно ей, любое расширение языка, не вызванное необходимостью, ухудшает его, так как приводит к усложнению транслятора и, соответственно, к понижению его надёжности и производительности. Одновременно возрастает сложность изучения языка и сложность сопровождения программ. Кроме того, сам факт наличия дополнительных синтаксических средств часто играет провоцирующую роль: он побуждает программиста прибегать к различным синтаксическим трюкам вместо того, чтобы глубже анализировать задачу и реализовывать более эффективные алгоритмы. Эти взгляды отразились в языках семейства Оберон, очень простых и практически лишённых синтаксического сахара.
Известен афоризм Алана Перлиса: «Синтаксический сахар вызывает рак точек с запятой». Точка с запятой («;»), являясь обязательной частью большинства популярных языков программирования, даже если в новом языке бесполезна, оставляется как необязательный элемент, так как большинство программистов имеют прочную привычку её использования. В оригинале афоризм обыгрывает созвучие английских слов semicolon (точка с запятой) и colon, последнее из которых означает не только двоеточие, но и прямую кишку (colon cancer — рак прямой кишки).
Чаще критика направляется на отдельные, часто встречающиеся виды синтаксического сахара: переопределение операций, свойства, сложные операции (вроде вышеупомянутой тернарной операции ?: в Си). Доводы критиков, в основном, сводятся к тому, что подобные средства, в действительности, не делают программу ни проще, ни понятнее, ни эффективнее, ни короче, но приводят к дополнительной трате ресурсов и усложняют восприятие, а значит и сопровождение программы.
Синтаксическая соль
С «синтаксическим сахаром» тесно связано понятие «синтаксическая соль» (англ. syntactic salt)[1] — на жаргоне хакеров конструкция в языке программирования, которая требует от программиста подтверждения того, что он делает. В отличие от «синтаксического сахара», который расширяет свободу выражения программиста, «синтаксическая соль» её сужает, требуя «без причины» писать длинные конструкции.
В Jargon File написано: «синтаксическая соль вредна, поскольку повышает артериальное давление хакера». Однако «промышленным» программистам, которые перегружены работой, зачастую рутинной, и квалификацией не дотягивают до хакеров, «синтаксическая соль» помогает не ошибаться.
Примеры:
- Директива
override
в Delphi: при изменении в базовом классе программист будет вынужден внести те же изменения в классы-потомки, иначе программа не будет компилироваться. - Операция
reinterpret_cast
в C++: как напоминание, что подобное преобразование типов небезопасно.
Примечания
Литература
В статье не хватает ссылок на источники (см. рекомендации по поиску). |