Синтаксический сахар

Синтаксический сахар(англ.syntactic sugar) вязыке программирования— этосинтаксическиевозможности, применение которых не влияет на поведение программы, но делает использование языка более удобным для человека.
Это может быть любой элемент синтаксиса, который даёт программисту альтернативный способ записи уже имеющейся в языке синтаксической конструкции, и при этом является более удобным, или более кратким, или похожим на другой распространённый способ записи, или помогает писать программы в хорошем стиле.
Под «синтаксическим сахаром» понимается любой имеющийся в языке программирования синтаксический элемент, механизм, способ описания, который дублирует другой, имеющийся в языке элемент или механизм, но является более удобным в использовании, или более краток, или выглядит естественнее, или более привычен (похож на аналогичные элементы других языков), или просто лучше воспринимается при чтении программы человеком. Принципиально то, что синтаксический сахар, теоретически, всегда можно удалить из языка без потери его возможностей — всё, что можно написать с применением синтаксического сахара, может быть написано на этом же языке и без него. Таким образом, синтаксический сахар предназначен лишь для того, чтобы сделать более удобным для программиста написание программы.
Понятие синтаксического сахара во многом условно. Его использование предполагает, что из всего множества синтаксических конструкций, имеющихся в языке, можно выделить некоторый «базовый набор», обеспечивающий функциональность языка, и дополнительные синтаксические средства, которые при желании можно выразить с помощью базового набора; последние и будут для данного языка синтаксическим сахаром. Однако многие конструкции являются взаимозаменяемыми, и далеко не всегда можно определённо сказать, какие именно из них являются базовыми, а какие — дополнительными. Например, в языкеМодула-2есть четыре видациклов:цикл с предусловием,цикл с постусловием, цикл с шагом ибезусловный цикл. Теоретически, первые три вида циклов могут быть легко выражены через последний. Являются ли они, в таком случае, синтаксическим сахаром? Обычно так не говорят, хотя формально под вышеприведённое определение они попадают.
Отнесение некоторых конструкций к синтаксическому сахару неоднозначно в силу исторических причин. Например, в языкеCи его потомках имеются операторыинкремента, декремента и составного присваивания (++,--,+=,-=и другие). Введение этих операторов в язык было вызвано необходимостью поддержки ручной оптимизации программ, так как код с их использованием мог транслироваться в более эффективные машинные команды («++a» транслировалось в одну команду INC, а аналогичное выражение «a=a+1» — в целую группу команд). Развитие технологии оптимизации кода сделало подобную ручную оптимизацию бессмысленной; сейчас компиляторы порождают одинаковый код для «длинного» и «короткого» варианта операции. В результате сокращённые операторы превратились в синтаксический сахар, хотя изначально им не были.
В некоторых случаях понятие «синтаксический сахар» трактуют более широко, нежели «другой способ записи для уже имеющихся синтаксических конструкций». Джек Креншоу в книге «Давайте создадим компилятор!»применяет этот термин к синтаксическим элементам, которые не нужны для правильной компиляции программы, а включаются в язык исключительно для обеспечения удобства программиста и для удобочитаемости программы:
В качестве примера такого синтаксического сахара приводится «then» в операторе «if» или «do» в операторе «while», а также точка с запятой: компилятор и без них однозначно определяет конец условия и место завершения оператора, но наличие этих конструкций делает программу более удобочитаемой. Очевидно, узкая трактовка понятия «синтаксический сахар» несовместима с широкой: вСиилиПаскаленевозможно записать операторы иным способом, без «then», «do» и точки с запятой. В таком случае уместно говорить о «синтаксическом мусоре». Учитывая же, что лишние в языке программирования слова — это лишние лексемы, то правильнее было бы применять термин «лексический мусор». С другой стороны, называть такие «лишние» элементы языка «мусором» не вполне корректно, ведь в действительности они могут существенно влиять на качество программирования, поскольку наличие избыточности в синтаксисе упрощает компилятору локализацию ошибок в коде. Рассмотрим пример на некоем условном Бейсик-подобном языке, где необязательно слово then в условном операторе и точка с запятой между операторами, а знак равенства может обозначать, в зависимости от положения, как логическое равенство, так и присваивание:
Здесь «a>b and k=20» — это условие, а «f=10» — ветвь «то». Однако если программист пропустит или случайно удалит оператор «and», конструкция превратится в:
Программа останется синтаксически корректной, но условием будет уже просто «a>b», а ветвью «то», в зависимости от правил языка, либо «k=20», превратившееся из условия в присваивание, либо оба оператора «k=20 f=10». В результате ошибки будет нарушено условие и произойдёт разрушение значения переменной k. Так как при внесении логической ошибки программа останется синтаксически верной, компилятор ошибки не заметит. Требование обязательного наличия служебного слова «then» между условием и оператором приведёт к тому, что компилятор обнаружит синтаксическую ошибку в условии. Обязательность точки с запятой между операторами также позволит компилятору обнаружить ошибку — отсутствие точки с запятой после оператора «k=20». Таким образом, наличие «сахарных» токенов, как и вообще любая избыточность в языке, приводит к тому, что логические ошибки в коде превращаются в синтаксические и могут быть обнаружены компилятором.
Термин «синтаксический сахар» (англ.syntactic sugar) был введёнПитером Лэндином(Peter J. Landin) в 1964 году для описания поверхностного синтаксиса простогоалголоподобногоязыка, семантически определяемого в терминахаппликативных выраженийлямбда-исчисленияс последующей чисто лексической заменой λ наwhere.
МассивывСипредставляют собой блоки впамяти. Доступ к элементам массива производится черезуказательна начало блока памяти (то есть, на начало массива) и смещение элемента относительно начального адреса. Это может быть записано без использования специального синтаксиса для массивов (a— указатель на начало массива,i— индекс элемента):*(a + i), но язык предоставляет специальный синтаксис:a[i]. Интересно, что можно использовать и формуi[a], совершенно логичную вследствие коммутативности операции сложения.
К синтаксическому сахару можно отнести ипереопределение операторов, поддерживаемое многими языками программирования. В принципе, любая операция может быть оформлена как процедура (функция, метод). Переопределение операторов позволяет выполнять операции, созданные программистом, внешне так же, как и встроенные в язык.
Ещё одним примером синтаксического сахара является концепция «свойств», поддерживаемая многими современными языками программирования. Имеется в виду объявление в классе псевдополей, которые внешне ведут себя как поля класса (имеют имя, тип, допускают присваивание и чтение), но в действительности таковыми не являются. Каждое обращение к свойству преобразуется компилятором в вызов метода доступа. Свойства совершенно не являются необходимыми (методы доступа можно вызывать и непосредственно) и используются исключительно для удобства, поскольку код с использованием свойств выглядит несколько проще и понятнее.
Не все программисты считают наличие синтаксического сахара в языках программирования и использование его программистами благом. Известна точка зренияНиклауса Вирта, которую разделяет часть программистского сообщества: согласно ей, любое расширение языка, не вызванное необходимостью, ухудшает его, так как приводит к усложнению транслятора и, соответственно, к понижению его надёжности и производительности. Одновременно возрастает сложность изучения языка и сложность сопровождения программ. Кроме того, сам факт наличия дополнительных синтаксических средств часто играет провоцирующую роль: он побуждает программиста прибегать к различным синтаксическим трюкам вместо того, чтобы глубже анализировать задачу и реализовывать более эффективные алгоритмы. Эти взгляды отразились в языках семействаОберон, очень простых и практически лишённых синтаксического сахара.
ИзвестенафоризмАлана Перлиса:«Синтаксический сахар вызывает рак точек с запятой».Точка с запятой(;), являясь обязательной частью большинства популярных языков программирования, даже если в новом языке бесполезна, оставляется как необязательный элемент, так как большинство программистов имеют прочную привычку её использования. В оригинале афоризм обыгрывает созвучие английских словsemicolon(«точка с запятой») иcolon, последнее из которых означает не только двоеточие, но и толстый кишечник (colon cancer— «рак толстого кишечника»).
Чаще критика направляется на отдельные, часто встречающиеся виды синтаксического сахара: переопределение операций, свойства, сложные операции (вродетернарной условной операции). Доводы критиков, в основном, сводятся к тому, что подобные средства, в действительности, не делают программу ни проще, ни понятнее, ни эффективнее, ни короче, но приводят к дополнительной трате ресурсов и усложняют восприятие, а значит и сопровождение программы.
В противоположность «синтаксическому сахару», понятие «синтаксическая соль» (англ.syntactic salt)на жаргоне программистов обозначает технически бесполезные конструкции в языке программирования, которые правила языка требуют употреблять при выполнении потенциально небезопасных действий. Они вводятся в язык только для того, чтобы, используя их, программист тем самым подтверждал, что сомнительное действие предпринято им сознательно, а не является случайной ошибкой или результатом непонимания. Как и «синтаксический сахар», «синтаксическая соль» не расширяет возможности языка и не нужна транслятору для корректной компиляции программы; она предназначена исключительно для людей, пользующихся данным языком. Классическим примером общеизвестной и широко применяемой «синтаксической соли» являются имеющиеся почти в любом языке со статической типизацией встроенные команды преобразования типов данных. Формально эти команды излишни (что демонстрирует классический Си, в котором любое преобразование типов допустимо и выполняется автоматически), но в языках, где их применение обязательно, программист вынужден каждый раз обращать внимание на то, что он выполняет потенциально опасное смешение типов, которое часто указывает на логическую ошибку в программе. В зависимости от строгости языка программирования использование «синтаксической соли» может быть обязательным или факультативным. В первом случае транслятор воспринимает её отсутствие как синтаксическую ошибку, во втором — выдаёт при трансляции предупреждение, которое программист может проигнорировать.
В отличие от «синтаксического сахара», который расширяет свободу выражения программиста, «синтаксическая соль» её сужает, требуя «без причины» писать длинные конструкции. ВJargon Fileнаписано: «синтаксическая соль вредна, поскольку повышает артериальное давление хакера». Действительно, при написании небольших программ, создаваемых и поддерживаемых одним человеком, предосторожности могут показаться излишними, однако при промышленной разработке крупных программных комплексов, поддерживаемых большими коллективами программистов, зачастую, к тому же, не самой высокой квалификации, «синтаксическая соль» помогает не ошибаться в разработке и эффективнее разбираться в коде, написанном другими разработчиками.
Примеры: