¿Cuál es la diferencia entre “Sintaxis” y “Azúcar sintáctica”?

45

Fondo

La página de Wikipedia en Syntactic Sugar dice:

  

En ciencias de la computación, el azúcar sintáctico es una sintaxis dentro de un lenguaje de programación que está diseñado para facilitar la lectura o la expresión. Hace que el lenguaje sea "más dulce" para que lo usen los humanos: las cosas se pueden expresar de forma más clara, más concisa o en un estilo alternativo que algunos prefieren.

Realmente no entiendo cuál es la diferencia entre Syntactic Sugar y Syntax.

Aprecio el punto de que la versión azucarada puede ser más clara, más concisa, tal vez hirviendo un poco de repetitivo. Pero creo que en algún nivel, toda la sintaxis es esencialmente hacer eso para formar una abstracción sobre lo que se compila el código.

Desde la misma página de Wikipedia:

  

Los procesadores de lenguaje, incluidos los compiladores, los analizadores estáticos y similares, a menudo expanden las construcciones azucaradas a construcciones más fundamentales antes del procesamiento, un proceso que a veces se denomina "desugaring".

Como ejercicio de pensamiento, si tomo "a menudo" en esta declaración para significar "siempre": si la diferencia fuera solo si el compilador "desugars" la sintaxis antes de pasar a la siguiente etapa, ¿cómo podría un programador que no lo hace? conocer las entrañas del compilador saber (o preocuparse) ¿qué es Sugar'd Syntax o no?

Una pregunta muy relacionada en este sitio "¿Definición rigurosa de azúcar sintáctica?" tiene una respuesta que comienza:

  

IMHO No creo que puedas tener una definición para el azúcar sintáctica, porque la frase es BS y es probable que la usen personas que hablan de "programadores reales" usando "herramientas reales" en "sistemas operativos reales"

¿Qué podría indicarme que tal vez no haya una gran diferencia en el codificador que usa el lenguaje? ¿Quizás la diferencia es solo perceptible para el escritor del compilador? ¿Aunque puede haber casos en los que sea útil para el programador que usa el lenguaje saber qué hay debajo del capó del azúcar sintáctica? (Pero tal vez en realidad, ¿algún discurso sobre el tema tiende a usar el término como cebo de llamas?)

El corazón de la pregunta

Entonces ... la versión corta de la pregunta:

  • ¿Existe una diferencia real entre Syntax y Syntactic Sugar?
  • ¿A quién le importa?

Alimento extra para el pensamiento

Bonus en la contradicción del tema:

En la página de Wikipedia se da un ejemplo:

  

Por ejemplo, en el lenguaje C, la notación a[i] es azúcar sintáctica para *(a + i)

Mientras que otra responde sobre las preguntas vinculadas anteriores habla del mismo ejemplo:

  

Ahora considera a[i] == *(a + i) . Piense en cualquier programa de C que use arreglos de cualquier manera sustancial.

Y resume que:

  

La notación [] facilita esta abstracción. No es azúcar sintáctica.

¡La conclusión opuesta para el mismo ejemplo!

    
pregunta Don Vince 05.04.2013 - 15:14

9 respuestas

34

La principal diferencia es que la sintaxis es la gramática definida en un lenguaje que le permite exponer algunas funciones. Tan pronto como pueda llegar a esa funcionalidad, cualquier sintaxis de otro que le permita hacer lo mismo se considera azúcar. Eso, por supuesto, se topa con escenarios impares sobre cuál de las dos sintaxis es el azúcar, especialmente porque no siempre está claro cuál fue el primero.

En la práctica, el azúcar sintáctico solo se usa para describir la sintaxis agregada a un lenguaje para facilitar su uso, como hacer que el infijo lhs + rhs map to lhs.Add(rhs) . Consideraría que la indexación de matriz de C es azúcar sintáctica.

Es importante sobre todo porque los diseños elegantes tienden a limitar la cantidad de duplicación. La necesidad (o, al menos, la falta) de azúcar sintáctica es vista por algunos como un signo de falla en el diseño.

    
respondido por el Telastyn 05.04.2013 - 15:36
10

La sintaxis es lo que un procesador de lenguaje usa para entender lo que significan las construcciones de un lenguaje. Las construcciones que se consideran azúcar sintáctica también deben ser interpretadas por el procesador de idiomas y, por lo tanto, forman parte de una sintaxis de idiomas.

Lo que diferencia al azúcar sintáctica del resto de la sintaxis de un lenguaje es que sería posible eliminar el azúcar sintáctico del lenguaje sin afectar los programas que se pueden escribir en el idioma.

Para dar una definición más formalista, diría

  

El azúcar sintáctico son aquellas partes de la sintaxis de un lenguaje cuyos efectos se definen en términos de otras construcciones de sintaxis en el lenguaje.

Esto no significa en modo alguno denigrar el azúcar sintáctico o los idiomas que lo contienen, porque el uso de azúcar sintáctico a menudo conduce a programas cuya intención es más comprensible.

    
respondido por el Bart van Ingen Schenau 05.04.2013 - 15:35
6

Las otras respuestas no han mencionado un concepto clave: sintaxis abstracta ; sin ella, el término "azúcar sintáctica" no tiene ningún sentido.

La sintaxis abstracta define los elementos y la estructura de los idiomas, y cómo las frases de ese lenguaje se pueden combinar para construir frases más grandes. La sintaxis abstracta es independiente de la sintaxis concreta. El término "azúcar sintáctica", según lo entiendo, se refiere a la sintaxis concreta.

En general, al diseñar un idioma, querrá crear una sintaxis concreta para cada término de su sintaxis abstracta, de modo que las personas puedan escribir código en su idioma con texto sin formato.

Ahora digamos que creas una sintaxis concreta incómoda para foo . Los usuarios se quejan y usted implementa una nueva sintaxis concreta para representar la misma sintaxis abstracta . El resultado es que su sintaxis abstracta y su semántica no han cambiado, pero ahora tiene dos sintaxis concretas para el mismo término de sintaxis abstracta.

Esto, creo, es lo que la gente quiere decir cuando dice "azúcar sintáctica": cambios que solo afectan la sintaxis concreta, pero que no afectan la sintaxis abstracta o la semántica.

Y así, la diferencia entre "azúcar sintáctica" y "sintaxis concreta" ahora es clara. A mi. :)

Esta interpretación también ayuda a explicar lo que Alan Perlis pudo haber querido decir cuando dijo que "el azúcar sintáctico causa cáncer de punto y coma": todo el azúcar sintáctica concreta en el mundo no puede corregir una sintaxis abstracta débil, y todo el esfuerzo que usted agrega. ese azúcar es un esfuerzo que no se gasta para enfrentar el problema real: la sintaxis abstracta.

También debo tener en cuenta que esta es únicamente mi opinión; Solo lo creo porque es la única interpretación que puedo pensar que tiene sentido para mí.

    
respondido por el user39685 05.04.2013 - 17:05
4

El azúcar sintáctica es un subconjunto de la sintaxis de idiomas. La idea básica es que hay más de una manera de decir lo mismo.

Lo que lo hace difícil es decir qué piezas son azúcar sintáctica y cuáles son "sintaxis pura" son declaraciones como "es difícil decir qué forma vino primero" o "es difícil saber de qué manera el autor del lenguaje intencionado "o" es un tanto arbitrario decidir qué forma es más simple ".

Lo que lo hace fácil para decidir qué piezas son puras o dulces es hacer la pregunta dentro del marco de un compilador o intérprete específico. La sintaxis pura es lo que un compilador convierte directamente en código de máquina o al que el intérprete responde directamente. El azúcar es lo que primero se convierte en algo de sintaxis antes de que ocurran estas cosas directas. Dependiendo de la implementación, esto puede o no ser lo mismo que pretendía el autor o incluso lo que afirma la especificación del idioma.

En la práctica, esta es la forma en que se decide la realidad del asunto.

    
respondido por el Jeff Wolski 06.04.2013 - 01:43
3

Realmente, tu primera cita de Wikipedia lo dice todo "... hace que las cosas sean más fáciles de leer ...", "... más dulce para que los humanos las usen ..."

Por escrito, las formas abreviadas como "no" o "no tener" podrían considerarse azúcar sintáctica.

    
respondido por el ozz 05.04.2013 - 17:14
3

Por lo general, la sintaxis de azúcar es la parte del lenguaje que puede expresarse mediante una parte existente del lenguaje (sintaxis) sin pérdida de generalidad pero con la pérdida de claridad. A veces, los compiladores tienen pasos de desugaring explícitos que transforman el AST creado por el código fuente y aplican pasos simples para eliminar los nodos correspondientes al azúcar.

Por ejemplo, Haskell tiene sintaxis de azúcar para las mónadas con las siguientes reglas 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

Ahora mismo no importa lo que signifique exactamente; sin embargo, puede ver que la sintaxis especial en LHS se puede transformar en algo más básico en RHS (es decir, aplicaciones de función, lambdas y let 's). Estos pasos permiten mantener lo mejor de ambos mundos:

  1. La sintaxis en LHS es más fácil para el programador (sintaxis de azúcar) que expresa las ideas existentes de una manera más clara
  2. Sin embargo, como el soporte en el compilador para construcciones RHS ya existe en el compilador, no es necesario que lo trate como algo especial fuera del analizador y la desincrustación (excepto para el informe de errores).

De manera similar, en C puede imaginar la regla de reescritura de desugaring (debido a la sobrecarga del operador, etc. no es cierto para C ++):

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

Podrías imaginarte escribiendo todos los programas sin usar -> o [] en C que usan esta construcción hoy. Sin embargo, sería más difícil para los programadores usarlo, por lo tanto, con azúcar de sintaxis (creo que en los años 70 podría simplificar el trabajo para los compiladores también). Posiblemente sea menos claro, ya que técnicamente puede agregar la siguiente regla de reescritura, perfectamente válida:

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

¿Es mala la sintaxis del azúcar? No necesariamente: existe el peligro de que se utilice como culto de carga sin comprender un significado más profundo. Por ejemplo, las siguientes funciones son equivalentes en Haskell, sin embargo, muchos principiantes escribirían la primera forma sin entender que están usando el azúcar de sintaxis en exceso:

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

Además, la sintaxis de azúcar puede complicar demasiado el lenguaje o ser demasiado estrecha para permitir el código idiomático generalizado. También podría significar que el lenguaje no es lo suficientemente poderoso como para hacer ciertas cosas fácilmente, podría ser por diseño (no le dé a los desarrolladores herramientas afiladas o un lenguaje de nicho muy específico que agregar un constructo más poderoso perjudicaría otros objetivos) u omisión, este último La forma dio a la sintaxis de azúcar el mal nombre. Si el lenguaje es lo suficientemente poderoso como para usar otras construcciones sin agregar azúcar de sintaxis, se considera más elegante usarlas.

    
respondido por el Maciej Piechotka 05.04.2013 - 22:20
3

Creo que el ejemplo más obvio sería la sintaxis "+=" en C.

i = i + 1;

y

 i +=  1;

haga exactamente lo mismo y compile exactamente el mismo conjunto de instrucciones de la máquina. La segunda forma guarda un par de caracteres al escribir, pero, lo que es más importante, deja muy claro que está modificando un valor en función de su valor actual.

Iba a citar al operador de prefijo / prefijo "++" como ejemplo canónico, pero me di cuenta de que esto era más que azúcar sintáctico. No hay manera de expresar la diferencia entre ++ i y i ++ en una sola expresión usando la sintaxis i = i + 1 .

    
respondido por el James Anderson 16.12.2013 - 02:25
1

Primero, abordaré algunas de las otras respuestas con un ejemplo concreto. El bucle para C ++ 11 basado en bucles (como los bucles foreach en otros idiomas)

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

es exactamente equivalente a (es decir, una versión azucarada de)

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

Ahora, a pesar de no agregar nueva sintaxis abstracta o semántica al lenguaje, tiene una utilidad real.

La primera versión hace explícita la intención (visitar cada elemento en un contenedor). También prohíbe comportamientos inusuales, como modificar el contenedor durante el recorrido, o avanzar más iterator en el cuerpo del bucle, o hacer que las condiciones del bucle sean sutilmente erróneas. Esto evita posibles fuentes de errores y, al hacerlo, reduce la dificultad de leer y razonar sobre el código.

Por ejemplo, un error de un carácter en la segunda versión:

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

da un error de un solo final y un comportamiento indefinido.

Por lo tanto, la versión azucarada es útil precisamente porque es más restrictiva y, por lo tanto, más sencilla de confiar & entender.

Segundo, a la pregunta original:

  

¿Hay una diferencia real entre Syntax y Syntactic Sugar?

No, "azúcar sintáctica" es una sintaxis del lenguaje (concreta), considerada "azúcar" porque no amplía la sintaxis abstracta o la funcionalidad principal del lenguaje. Me gusta la respuesta de Matt Fenwick sobre esto.

  

¿A quién le importa?

Es importante para los usuarios del lenguaje, tanto como cualquier otra sintaxis, y en ese sentido se proporciona azúcar para apoyar (y en cierto sentido, bendecir) expresiones idiomáticas específicas.

Finalmente, en la pregunta de bonificación

  

La notación [] facilita esta abstracción.

esto se parece mucho a la definición de azúcar sintáctica: apoya (y proporciona la bendición para los autores del idioma) utilizando punteros como matrices. La forma p[i] no es realmente más restrictiva que *(p+i) , por lo que la única diferencia es la comunicación clara de la intención (y una leve ganancia de legibilidad).

    
respondido por el Useless 05.04.2013 - 17:32
0
Cualquiera sea la connotación original de la frase, hoy en día es principalmente un peyorativo, casi siempre expresado como "solo" o "solo" azúcar sintáctica. Bastante importa solo a los programadores que les gusta hacer las cosas de forma ilegible y quieren una forma concisa para justificar eso ante sus colegas. Una definición por parte de quienes usan el término hoy, desde su punto de vista, sería algo como:

  

Sintaxis que es redundante con otra sintaxis más ampliamente aplicable, en   Para proporcionar una muleta para los programadores que realmente no entienden   el idioma.

Es por eso que obtiene dos conclusiones opuestas para el mismo elemento sintáctico. Su primer ejemplo en notación matricial es usar el significado positivo original del término, algo similar a la respuesta de Bart. Su segundo ejemplo es defender la notación matricial contra la acusación de ser azúcar sintáctica en el sentido peyorativo. En otras palabras, argumenta que la sintaxis es una abstracción útil en lugar de una muleta.

    
respondido por el Karl Bielefeldt 05.04.2013 - 16:49

Lea otras preguntas en las etiquetas