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 fraseMOVE 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 aa = a + b
em C e linguagens semelhantes, supondoa
que não tenha efeitos colaterais, como sea
for 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 paraif (not condition) {...}
. Além disso, qualquer instrução pode ser seguida por uma condição, entãostatement if condition
é equivalente aif (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, aa->x
notação é um açúcar sintático para acessar membros usando o operador de desreferência(*a).x
. - A
using
instruçã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 dex
da expressãoexpr
, em vez de exigir uma declaração de tipo explícita. Da mesma forma, C ++ permiteauto x = expr
desde C ++ 11 e Java permitevar x = expr
desde 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 af(x,y)
. - Em SQL ,
JOIN
é equivalente aINNER 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
import
declaraçã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 , comojavax.swing.JButton
usar o nome mais curtoJButton
.
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 new
palavra-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 break
para cada não-vazia case
etiqueta de um switch
(a menos que goto
, return
ou throw
é usado), mesmo que ele não permite implícita queda-through . (Usando goto
e 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
- Abelson, Harold ; Sussman, Gerald Jay ; Sussman, Julie (1996) [1984]. Estrutura e Interpretação de Programas de Computador . Cambridge, MA: MIT Press . ISBN 0-262-51087-1.
- Landin, Peter J. (fevereiro-março de 1965). "Uma correspondência entre o ALGOL 60 e a notação lambda da Igreja: partes I e II". Comunicações da ACM . 8 (2,3): 89–101, 158–165. doi : 10.1145 / 363744.363749 . S2CID 6505810 .
- Landin, Peter J. (março de 1965). "Programação sem imperativos - um exemplo". UNIVAC Systems Programming Research .
- Landin, Peter J. (julho de 1965). "Livrando-se dos rótulos". UNIVAC Systems Programming Research .
-
Landin, Peter J. (agosto de 1965). "Uma generalização de saltos e rótulos". UNIVAC Systems Programming Research ., reimpresso em " Higher-Order and Symbolic Computation ". 11 . 1998: 125–143. CiteSeerX 10.1.1.85.2610 . Citar diário requer
|journal=
( ajuda ) - Perlis, AJ (setembro de 1982). "Epigramas sobre programação" . Avisos ACM SIGPLAN . Nova York, NY, EUA: Association for Computing Machinery. 17 (9): 7–13. doi : 10.1145 / 947955.1083808 . S2CID 20512767 . Arquivado do original em 17 de janeiro de 1999.