В информатике синтаксический сахар — это синтаксис в языке программирования , который разработан для того, чтобы сделать вещи более легкими для чтения или выражения. Он делает язык «слаще» для человеческого использования: вещи могут быть выражены более ясно, более кратко или в альтернативном стиле, который некоторые могут предпочесть. Синтаксический сахар обычно является сокращением для общей операции, которая также может быть выражена в альтернативной, более многословной форме: у программиста есть выбор, использовать ли более короткую или длинную форму, но обычно он будет использовать более короткую форму, поскольку она короче и ее легче набирать и читать.
Например, многие языки программирования предоставляют специальный синтаксис для ссылки на элементы массива и их обновления . Абстрактно, ссылка на массив — это процедура из двух аргументов: массива и вектора индекса, которая может быть выражена как get_array(Array, vector(i,j))
. Вместо этого многие языки предоставляют такой синтаксис, как Array[i,j]
. Аналогично обновление элемента массива — это процедура, состоящая из трех аргументов, например set_array(Array, vector(i,j), value)
, но многие языки также предоставляют такой синтаксис, как Array[i,j] = value
.
Конструкция в языке является синтаксическим сахаром, если ее можно удалить из языка, не оказав никакого влияния на его возможности: функциональность и выразительная сила останутся прежними.
Языковые процессоры, включая компиляторы и статические анализаторы , часто расширяют засахаренные конструкции до их более подробных эквивалентов перед обработкой; этот процесс иногда называют «десахаризацией».
Термин «синтаксический сахар» был придуман Питером Дж. Ландином в 1964 году для описания поверхностного синтаксиса простого языка программирования, подобного АЛГОЛу , который был определён семантически в терминах аппликационных выражений лямбда-исчисления [ 1] [2], сосредоточенных на лексической замене λ на «where».
Более поздние языки программирования, такие как CLU , ML и Scheme , расширили этот термин, чтобы обозначить синтаксис в языке, который можно было определить в терминах языкового ядра основных конструкций; удобные, высокоуровневые функции можно было «десахарить» и разложить на это подмножество. [3] Это, по сути, обычная математическая практика построения из примитивов.
Основываясь на различии Ландина между основными языковыми конструкциями и синтаксическим сахаром, в 1991 году Маттиас Феллейзен предложил кодификацию «выразительной силы», чтобы соответствовать «широко распространенным убеждениям» в литературе. Он определил «более выразительный» как означающий, что без рассматриваемых языковых конструкций программу пришлось бы полностью реорганизовать. [4]
MOVE A B.
и предложение MOVE A TO B.
выполняют абсолютно одну и ту же функцию, но второе делает действие, которое должно быть выполнено, более понятным.a += b
эквивалентно a = a + b
в C и подобных языках, предполагая, что a
не имеет побочных эффектов, таких как если бы a
это была обычная переменная. [5] [6] Некоторые языки, такие как Python [7], могут допускать перегрузку операторов расширенного присваивания, поэтому они могут вести себя иначе, чем стандартные.unless (condition) {...}
это синтаксический сахар для if (not condition) {...}
. Кроме того, за любым оператором может следовать условие, поэтому statement if condition
эквивалентно if (condition) {statement}
, но первый более естественно отформатирован в одну строку.a[i]
нотация является синтаксическим сахаром для *(a + i)
. [8] Аналогично, эта a->x
нотация является синтаксическим сахаром для доступа к членам с использованием оператора разыменования (*a).x
.using
в C# обеспечивает правильное удаление определенных объектов. Компилятор расширяет оператор в блок try-finally . [9]var x = expr
, что позволяет компилятору выводить тип x
из выражения expr
, вместо того, чтобы требовать явного объявления типа. Аналогично, C++ позволяет auto x = expr
с C++11, а Java позволяет var x = expr
с Java 11.[x*x for x in range(10)]
для списка квадратов) и декораторы (например, @staticmethod
).%>%
x %>% f(y)
f(x,y)
JOIN
эквивалентно INNER JOIN
, последнее поясняет, что оператор join является именно внутренней операцией соединения, а не внешней операцией соединения. Аналогично, можно опустить OUTER
из LEFT OUTER JOIN
, RIGHT OUTER JOIN
и FULL OUTER JOIN
.myObject.myMethod(parameter1, parameter2, parameter3)
является синтаксическим сахаром для вызова глобальной функции как . Ссылка на объект передается как скрытый аргумент, обычно доступный изнутри метода как .myMethod(myObject, parameter1, parameter2, parameter3)
this
import
позволяет компилятору находить классы, которые не указаны иным образом с полными именами. Например, import javax.swing.*;
позволяет программисту ссылаться на объект Swing , например, javax.swing.JButton
используя более короткое имя JButton
.(x) => x + 1
(x) => { return x + 1; }
???
) эквивалентен throw new NotImplementedError
. Это полезно для обозначения места для кода, который еще не был написан. [11]Некоторые программисты считают, что эти особенности удобства использования синтаксиса либо неважны, либо совершенно несерьёзны. В частности, специальные синтаксические формы делают язык менее однородным, а его спецификацию более сложной, и могут вызывать проблемы, когда программы становятся большими и сложными. Эта точка зрения особенно распространена в сообществе Lisp , поскольку у Lisp очень простой и регулярный синтаксис, а поверхностный синтаксис можно легко изменить. [12] Например, Алан Перлис однажды пошутил в « Эпиграммах программирования », ссылаясь на языки, разделяемые скобками , что «Синтаксический сахар вызывает рак точек с запятой ». [13]
Метафора была расширена путем введения термина «синтаксическая соль» , который обозначает функцию, призванную усложнить написание плохого кода. [14] В частности, синтаксическая соль — это обруч, через который программисты должны прыгнуть, чтобы доказать, что они знают, что происходит, а не чтобы выразить действие программы.
В C# при скрытии унаследованного члена класса выдается предупреждение компилятора, если только new
ключевое слово не используется для указания того, что скрытие является преднамеренным. [15] Чтобы избежать потенциальных ошибок из-за сходства синтаксиса оператора switch с синтаксисом C или C++, C# требует break
для каждой непустой case
метки a switch
(если только goto
не используется return
, или ), даже если он не допускает неявного провала . [16] (Использование и указание последующей метки приводит к провалу , подобному C/C++ .)throw
goto
Синтаксическая соль может свести на нет свое предназначение, сделав код нечитаемым и, таким образом, ухудшив его качество — в крайних случаях основная часть кода может оказаться короче, чем накладные расходы, введенные для удовлетворения языковых требований.
Альтернативой синтаксической соли является генерация предупреждений компилятора, когда существует высокая вероятность того, что код является результатом ошибки — практика, распространенная в современных компиляторах C/C++.
Другие расширения — это синтаксический сахарин и синтаксический сироп , то есть беспричинный синтаксис, который не делает программирование проще. [17] [18] [19] [20]
Типы данных с базовой синтаксической поддержкой называются «сахаренными типами». [21] [22] [23] Распространенными примерами являются строки, разделенные кавычками, фигурные скобки для типов объектов и записей, а также квадратные скобки для массивов.
выражение составного присваивания не эквивалентно расширенной версии, поскольку выражение составного присваивания вычисляет expression1 только один раз, тогда как расширенная версия вычисляет expression1 дважды: в операции сложения и в операции присваивания.
оптимизация может [быть выполнена], если «нахождение x» не имеет побочных эффектов
{{cite journal}}
: Цитировать журнал требует |journal=
( помощь )