Qual é a diferença entre “Syntax” e “Syntactic Sugar”?

45

Antecedentes

A página da Wikipedia sobre o Açúcar Sintático afirma:

In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language "sweeter" for humans to use: things can be expressed more clearly, more concisely, or in an alternative style that some may prefer.

Eu realmente não entendo qual é a diferença entre o Syntactic Sugar e o Syntax.

Eu aprecio o ponto de que a versão açucarada pode ser mais clara, mais concisa, talvez extrair algum clichê. Mas eu sinto que em algum nível, toda a sintaxe está essencialmente fazendo isso para formar uma abstração sobre o que o código é compilado para baixo.

Da mesma página da Wikipédia:

Language processors, including compilers, static analyzers, and the like, often expand sugared constructs into more fundamental constructs before processing, a process sometimes called "desugaring".

Como um exercício de pensamento, se eu tomar "frequentemente" nesta declaração para significar "sempre": Se a diferença fosse apenas se o compilador "desugaria" a sintaxe antes de passar para a próxima etapa, como poderia um codificador que não sabe as entranhas do compilador sabem (ou cuidado) o que é Sintaxe Açucarada ou não?

Uma pergunta muito relacionada neste site "Definição Rigorosa do Açúcar Sintático?" tem uma resposta que começa:

IMHO I don't think you can have a definition for syntactic sugar, because the phrase is BS and is likely to be used by people that talk about "real programmers" using "real tools" on "real operating systems"

O que pode indicar para mim que talvez não exista uma grande diferença para o codificador usando a linguagem? Talvez a diferença só seja perceptível para o compilador? Embora possa haver casos em que é útil para o codificador usando a linguagem para saber o que está sob o capô do Açúcar Sintático? (Mas talvez, na realidade, qualquer discurso sobre o assunto tenda a usar o termo como isca de fogo?)

O coração da questão

Então ... a versão curta da pergunta:

  • Existe uma diferença real entre o Syntax e o Syntactic Sugar?
  • Para quem isso importa?

Alimento extra para o pensamento

Bônus na contradição do tópico:

Na página da Wikipédia, um exemplo é dado:

For instance, in the C language the a[i] notation is syntactic sugar for *(a + i)

Considerando que outra resposta na questão relacionada acima fala sobre o mesmo exemplo:

Now consider a[i] == *(a + i). Think about any C program that uses arrays in any substantive way.

E resume isso:

The [] notation facilitates this abstraction. It's not syntactic sugar.

A conclusão oposta para o mesmo exemplo!

    
por Don Vince 05.04.2013 / 15:14
fonte

9 respostas

34

A principal diferença é que a sintaxe é a gramática definida em um idioma para permitir que você exponha algumas funcionalidades. Assim que você puder acessar essa funcionalidade, qualquer outra outra sintaxe que permita fazer a mesma coisa é considerada açúcar. Isso, claro, é executado em cenários estranhos sobre qual das duas sintaxes é o açúcar, especialmente porque nem sempre é claro o que veio primeiro.

Na prática, o açúcar sintático é usado apenas para descrever a sintaxe adicionada a um idioma para facilitar a facilidade de uso, como a criação do infix lhs + rhs map para lhs.Add(rhs) . Eu consideraria a indexação de array de C como açúcar sintático.

É importante principalmente porque designs elegantes tendem a limitar a quantidade de duplicação. A necessidade (ou pelo menos o desejo) de açúcar sintático é vista por alguns como um sinal de falha no design.

    
por 05.04.2013 / 15:36
fonte
10

A sintaxe é o que um processador de linguagem usa para entender o que significam as construções de uma linguagem. Os construtos que são considerados açúcar sintático também precisam ser interpretados pelo processador de linguagem e, portanto, fazem parte de uma sintaxe de linguagens.

O que diferencia o açúcar sintático do resto da sintaxe de uma linguagem é que seria possível remover o açúcar sintático da linguagem sem afetar os programas que podem ser escritos na linguagem.

Para dar uma definição mais formal, eu diria

Syntactic sugar are those parts of a language's syntax whose effects are defined in terms of other syntax constructs in the language.

Isso não significa de forma alguma denegrir o açúcar sintático, ou as linguagens que o contêm, porque o uso do açúcar sintático muitas vezes leva a programas cuja intenção é mais compreensível.

    
por 05.04.2013 / 15:35
fonte
6

As outras respostas não mencionaram um conceito chave: sintaxe abstrata ; sem isso, o termo "açúcar sintático" não faz sentido.

A sintaxe abstrata define os elementos e a estrutura das linguagens e como as frases dessa linguagem podem ser combinadas para construir frases maiores. A sintaxe abstrata é independente da sintaxe concreta. O termo "açúcar sintático", como eu o entendo, refere-se à sintaxe concreta.

Em geral, ao criar uma linguagem, você desejará criar uma sintaxe concreta para cada termo da sua sintaxe abstrata, para que as pessoas possam escrever código em seu idioma usando texto simples.

Agora, digamos que você crie uma sintaxe concreta e desajeitada para foo . Os usuários reclamam e você implementa uma nova sintaxe concreta para representar a mesma sintaxe abstrata . O resultado é que sua sintaxe abstrata e semântica não mudaram, mas agora você tem duas sintaxes concretas para o mesmo termo de sintaxe abstrata.

Isso, eu acredito, é o que as pessoas querem dizer quando dizem "açúcar sintático" - mudanças que afetam apenas a sintaxe concreta, mas que não afetam a sintaxe abstrata ou a semântica.

E assim a diferença entre "açúcar sintático" e "sintaxe concreta" está clara agora. Para mim. :)

Esta interpretação também ajuda a explicar o que Alan Perlis poderia ter significado quando disse "o açúcar sintático causa o câncer do ponto-e-vírgula": todo o açúcar sintático concreto no mundo não pode corrigir a sintaxe abstrata fraca, e todo o esforço que você gasta adicionando que o açúcar é um esforço que você não está gastando para lidar com o problema real - a sintaxe abstrata.

Eu também devo observar que isso é apenas minha opinião; Eu só acredito nisso porque é a única interpretação em que consigo pensar que faz sentido para mim.

    
por 05.04.2013 / 17:05
fonte
4

O açúcar sintático é um subconjunto da sintaxe das linguagens. A ideia básica é que há mais de uma maneira de dizer a mesma coisa.

O que torna difícil dizer quais peças são açúcar sintático e quais partes são "sintaxe pura" são declarações como "é difícil dizer qual forma veio primeiro" ou "é difícil saber qual caminho o autor da linguagem pretendida "ou" é um tanto arbitrário decidir qual forma é mais simples ".

O que torna fácil decidir quais partes são puras ou açucaradas é fazer a pergunta dentro do quadro de um compilador ou interpretador específico. A sintaxe pura é o material que um compilador converte diretamente em código de máquina ou que o interpretador responde diretamente. O açúcar é o material que primeiro é transformado em alguma outra sintaxe antes que essas coisas diretas aconteçam. Dependendo da implementação, isso pode ou não ser o mesmo que o autor pretendeu ou até mesmo o que a especificação da linguagem exige.

Na prática, é assim que a realidade do assunto é decidida.

    
por 06.04.2013 / 01:43
fonte
3

Realmente, sua primeira citação da Wikipedia diz tudo "... torna as coisas mais fáceis de ler ...", ".... mais doce para os humanos usarem ....".

Por escrito, formas encurtadas como "não" ou "não" podem ser consideradas açúcar sintático.

    
por 05.04.2013 / 17:14
fonte
3

Normalmente, o açúcar de sintaxe é a parte da linguagem que pode ser expressa pela parte existente da linguagem (sintaxe) sem perda de generalidade, mas com clareza possivelmente perdida. Às vezes, os compiladores têm uma etapa explícita de dessachamento, que transforma a AST criada pelo código-fonte e aplica etapas simples para remover os nós correspondentes ao açúcar.

Por exemplo, o Haskell tem o açúcar da sintaxe para as mônadas com as seguintes regras aplicadas recursivamente

do { f }            ~> f
do { g; h }         ~> g >> do h
do { x <- f; h }    ~> f >>= \x -> do h
do { let x = f; h } ~> let x = f in do h

Neste momento, não importa o que isso significa exatamente - no entanto, você pode ver que a sintaxe especial em LHS pode ser transformada em algo mais básico em RHS (ou seja, aplicativos de função, lambdas e let ). Esta etapa permite manter o melhor dos dois mundos:

  1. A sintaxe no LHS é mais fácil para o programador (syntax sugar) expressar as ideias existentes de maneira mais clara
  2. No entanto, como o suporte no compilador para construções RHS já existe no compilador, ele não precisa tratá-lo como algo especial fora do analisador e do dessachamento (exceto para relatório de erros).

Da mesma forma, em C, você pode imaginar a regra de reescrita de dessachamento (devido à sobrecarga do operador, etc., que não é verdadeira para o C ++):

f->h ~> (*f).h
f[h] ~> *(f + h)

Você pode imaginar escrever todos os programas sem usar -> ou [] em C que usam essa construção hoje. No entanto, seria mais difícil para os programadores usá-lo, portanto, desde açúcar sintaxe (eu acho que nos anos 70 pode simplificar o trabalho para compiladores também). Talvez seja menos claro, já que você pode adicionar tecnicamente a seguinte regra de reescrita perfeitamente válida:

*f ~> f[0] -- * and [] have the same expressiveness 

A sintaxe do açúcar é ruim? Não necessariamente - há o perigo de que seja usado como culto de carga sem entender um significado mais profundo. Por exemplo, as seguintes funções são equivalentes em Haskell, ainda que muitos iniciantes escrevam a primeira forma sem entender que estão usando excessivamente o açúcar da sintaxe:

f1 = do x <- doSomething
        return x
f2 = doSomething

Além disso, o açúcar da sintaxe pode complicar demais a linguagem ou ser muito estreito para permitir um código idiomático generalizado. Também pode significar que a linguagem não é poderosa o suficiente para fazer certas coisas facilmente - pode ser por design (não dê ferramentas afiadas aos desenvolvedores ou linguagem de nicho muito específica que adicionar construções mais poderosas prejudicaria outros objetivos) ou por omissão - as últimas forma deu a sintaxe de açúcar o nome ruim. Se a linguagem for poderosa o suficiente para usar outras construções sem adicionar sintaxe, é considerado mais elegante usá-las.

    
por 05.04.2013 / 22:20
fonte
3

Acho que o exemplo mais óbvio seria a sintaxe "+=" em C.

i = i + 1;

e

 i +=  1;

faça exatamente a mesma coisa e compile exatamente o mesmo conjunto de instruções de máquina. O segundo formulário salva alguns caracteres digitando, mas, mais importante, deixa claro que você está modificando um valor com base em seu valor atual.

Eu ia citar o operador "+ ++" post / prefix como o exemplo canônico, mas percebi que isso era mais do que açúcar sintático. Não há como expressar a diferença entre o ++ i e o i ++ em uma única expressão usando a sintaxe i = i + 1 .

    
por 16.12.2013 / 02:25
fonte
1

Primeiro, vou abordar algumas das outras respostas com um exemplo concreto. O loop baseado em intervalo do C ++ 11 (muito parecido com loops foreach em várias outras linguagens)

for (auto value : container) {
    do_something_with(value);
}

é exatamente equivalente a (ou seja, uma versão açucarada de)

for (auto iterator = begin(container); iterator != end(container); ++iterator) {
    do_something_with(*iterator);
}

Agora, apesar de não adicionar nenhuma nova sintaxe abstrata ou semântica à linguagem, ela tem utilidade real.

A primeira versão torna explícita a intenção (visitar cada item em um contêiner). Ele também proíbe comportamentos incomuns, como modificar o contêiner durante o percurso, ou avançar ainda mais o iterator no corpo do loop, ou fazer com que as condições do loop fiquem sutilmente erradas. Isso evita possíveis fontes de erros e, ao fazê-lo, reduz a dificuldade de leitura e raciocínio sobre o código.

Por exemplo, um erro de um caractere na segunda versão:

for (auto iterator = begin(container); iterator <= end(container); ++iterator) {
    do_something_with(*iterator);
}

gera um erro de um a um e o final e um comportamento indefinido.

Assim, a versão açucarada é útil precisamente porque é mais restritiva e, portanto, mais simples de confiar & entender.

Em segundo lugar, para a pergunta original:

Is there a real difference between Syntax and Syntactic Sugar?

Não, "açúcar sintático" é a sintaxe da linguagem (concreta), considerada "açúcar" porque não estende a sintaxe abstrata nem a funcionalidade principal da linguagem. Eu gosto da resposta de Matt Fenwick sobre isso.

Who does it matter to?

É importante para os usuários do idioma, tanto quanto qualquer outra sintaxe, e em que o açúcar é fornecido para apoiar (e, de alguma forma, abençoar) idiomas específicos.

Finalmente, na questão bônus

The [] notation facilitates this abstraction.

isso soa muito como a definição do açúcar sintático: ele suporta (e fornece a bênção dos autores da linguagem) usando ponteiros como matrizes. A forma p[i] não é realmente mais restritiva que *(p+i) , então a única diferença é a clara comunicação da intenção (e um pequeno ganho de legibilidade).

    
por 05.04.2013 / 17:32
fonte
0
Seja qual for a conotação original da frase, hoje em dia é principalmente um pejorativo, quase sempre expresso como açúcar sintático "justo" ou "apenas". Isso só é importante para programadores que gostam de fazer as coisas da maneira ilegível e querem uma forma concisa de justificar isso para seus colegas. Uma definição daqueles que usam principalmente o termo hoje, do ponto de vista deles, seria algo como:

Syntax that is redundant with other more widely applicable syntax, in order to provide a crutch for programmers who don't really understand the language.

É por isso que você tem duas conclusões opostas para o mesmo elemento sintático. Seu primeiro exemplo de notação de array é usar o significado positivo original do termo, algo semelhante à resposta de Bart. Seu segundo exemplo é defender a notação de array contra a acusação de ser açúcar sintático no sentido pejorativo. Em outras palavras, está argumentando que a sintaxe é uma abstração útil em vez de uma muleta.

    
por 05.04.2013 / 16:49
fonte