Açúcar sintático - Syntactic sugar

Na ciência da computação , o açúcar sintático é a sintaxe de uma linguagem de programação projetada para tornar as coisas mais fáceis de ler ou expressar. Isso torna a linguagem "mais doce" para uso humano: as coisas podem ser expressas de forma mais clara, mais concisa ou em um estilo alternativo que alguns possam preferir.

Por exemplo, muitas linguagens de programação fornecem sintaxe especial para referência e atualização de elementos de array . Abstratamente, uma referência de array é um procedimento de dois argumentos: um array e um vetor subscrito, que pode ser expresso como get_array(Array, vector(i,j)). Em vez disso, muitas linguagens fornecem sintaxe como Array[i,j]. Da mesma forma, uma atualização de elemento de matriz é um procedimento que consiste em três argumentos, por exemplo set_array(Array, vector(i,j), value), mas muitas linguagens fornecem sintaxe como Array[i,j] = value.

Uma construção em uma linguagem é um açúcar sintático se puder ser removida da linguagem sem qualquer efeito sobre o que a linguagem pode fazer: a funcionalidade e o poder expressivo permanecerão os mesmos.

Processadores de linguagem, incluindo compiladores e analisadores estáticos , freqüentemente expandem construções açucaradas em construções mais fundamentais antes do processamento, um processo às vezes chamado de "desugaring".

Origens

O termo açúcar sintático foi cunhado por Peter J. Landin em 1964 para descrever a sintaxe de superfície de uma linguagem de programação semelhante ao ALGOL , que foi definida semanticamente em termos das expressões aplicativas do cálculo lambda , centrado na substituição lexical de λ por "onde".

Linguagens de programação posteriores, como CLU , ML e Scheme , estenderam o termo para se referir à sintaxe dentro de uma linguagem que poderia ser definida em termos de um núcleo de linguagem de construções essenciais; os recursos convenientes e de nível superior poderiam ser "desavucados" e decompostos nesse subconjunto. Esta é, de fato, a prática matemática usual de construir a partir de primitivos.

Com base na distinção de Landin entre construções essenciais de linguagem e açúcar sintático, em 1991, Matthias Felleisen propôs uma codificação de "poder expressivo" para se alinhar com "crenças amplamente aceitas " na literatura. Ele definiu "mais expressivo" para significar que, sem as construções de linguagem em questão, um programa teria que ser completamente reorganizado.

Exemplos notáveis

  • No COBOL , muitas das palavras-chave intermediárias são açúcares sintáticos que podem ser omitidos opcionalmente. Por exemplo, a frase MOVE A B.e a frase MOVE A TO B.desempenham exatamente a mesma função, mas a segunda torna a ação a ser executada mais clara.
  • Atribuição aumentada ou operadores de atribuição composta: por exemplo, a += bé equivalente a a = a + bem C e linguagens semelhantes, supondo aque não tenha efeitos colaterais, como se afor uma variável regular. Algumas linguagens, como Python, podem permitir a sobrecarga de operadores de atribuição aumentada, portanto, eles podem se comportar de maneira diferente dos padrões.
  • Em Perl , unless (condition) {...} é o açúcar sintático para if (not condition) {...}. Além disso, qualquer instrução pode ser seguida por uma condição, então statement if conditioné equivalente a if (condition) {statement}, mas a primeira é mais naturalmente formatada em uma única linha.
  • Na linguagem C , a a[i]notação é um açúcar sintático para *(a + i). Da mesma forma, a a->xnotação é um açúcar sintático para acessar membros usando o operador de desreferência (*a).x .
  • A usinginstrução em C # garante que certos objetos sejam descartados corretamente. O compilador expande a instrução em um bloco try-finally.
  • A linguagem C # permite que variáveis ​​sejam declaradas como var x = expr, o que permite ao compilador inferir o tipo de xda expressão expr, em vez de exigir uma declaração de tipo explícita. Da mesma forma, C ++ permite auto x = exprdesde C ++ 11 e Java permite var x = exprdesde Java 11.
  • Compreensões de lista Python (como [x*x for x in range(10)]para uma lista de quadrados) e decoradores (como @staticmethod).
  • Em Haskell , uma string, denotada entre aspas, é semanticamente equivalente a uma lista de caracteres.
  • No tidyverse recolha de R pacotes, o tubo , indicado por %>%, declara que os dados (ou de saída da função) anteriores o tubo irá servir como o primeiro argumento para a função seguinte do tubo. Portanto, x %>% f(y)é equivalente a f(x,y).
  • Em SQL , JOINé equivalente a INNER JOIN, o último esclarecendo que a instrução de junção é especificamente uma operação de junção interna em oposição a uma operação de junção externa.
  • O método que chama em linguagens OOP na forma de myObject.myMethod(parameter1, parameter2, parameter3)é um açúcar sintático para chamar uma função global como . A referência ao objeto é passada como um argumento oculto, geralmente acessível de dentro do método como .myMethod(myObject, parameter1, parameter2, parameter3)this
  • Parâmetros chamados por referência são um açúcar de sintaxe para passar tecnicamente um ponteiro para o parâmetro, mas manipulá-lo sintaticamente como a própria variável, para evitar a desreferenciação constante do ponteiro no código dentro da função.
  • Em Java , uma importdeclaração permite que o compilador encontre classes que não são especificadas de outra forma com nomes totalmente qualificados. Por exemplo, import javax.swing.*;permite que o programador faça referência a um objeto Swing , como javax.swing.JButtonusar o nome mais curto JButton.

Crítica

Alguns programadores acham que esses recursos de usabilidade da sintaxe são sem importância ou completamente frívolos. Notavelmente, as formas sintáticas especiais tornam a linguagem menos uniforme e sua especificação mais complexa, e podem causar problemas à medida que os programas se tornam grandes e complexos. Esta visão é particularmente difundida na comunidade Lisp , pois Lisp tem uma sintaxe muito simples e regular, e a sintaxe de superfície pode ser facilmente modificada. Por exemplo, Alan Perlis uma vez brincou em " Epigramas sobre programação ", em uma referência a linguagens delimitadas por colchetes , que "açúcar sintático causa câncer de ponto -e-vírgula ".

Termos derivados

Sal sintático

A metáfora foi estendida com a criação do termo sal sintático , que indica um recurso projetado para dificultar a escrita de código incorreto. Especificamente, o sal sintático é um obstáculo que os programadores devem percorrer apenas para provar que sabem o que está acontecendo, em vez de expressar uma ação do programa. Por exemplo, em Java e Pascal, atribuir um valor float a uma variável declarada como um int sem sintaxe adicional declarando explicitamente que a intenção resultará em um erro de compilação, enquanto C e C ++ truncarão automaticamente quaisquer floats atribuídos a um int. No entanto, isso não é sintaxe, mas semântica.

Em C # , ao ocultar um membro da classe herdada, um aviso do compilador é emitido, a menos que a newpalavra-chave seja usada para especificar que a ocultação é intencional. Para evitar possíveis erros devido à similaridade da instrução switch sintaxe com a de C ou C ++, C # requer um breakpara cada não-vazia caseetiqueta de um switch(a menos que goto, returnou throwé usado), mesmo que ele não permite implícita queda-through . (Usando gotoe especificando o rótulo subsequente produz um C / C ++ - como queda-through ).

O sal sintático pode anular seu propósito ao tornar o código ilegível e, assim, piorar sua qualidade - em casos extremos, a parte essencial do código pode ser mais curta do que a sobrecarga introduzida para satisfazer os requisitos de linguagem.

Uma alternativa ao salt sintático é gerar avisos do compilador quando houver alta probabilidade de que o código seja resultado de um erro - uma prática comum nos compiladores C / C ++ modernos.

Sacarina sintática

Outras extensões são sacarina sintática e xarope sintático , o que significa sintaxe gratuita que não torna a programação mais fácil.

Tipos açucarados

Os tipos de dados com suporte sintático central são chamados de "tipos açucarados". Os exemplos comuns incluem strings delimitadas por aspas, chaves para objetos e tipos de registro e colchetes para matrizes.

Notas

Referências