
En informática , el azúcar sintáctico es una sintaxis dentro de un lenguaje de programación diseñada para facilitar la lectura y la expresión del código. Hace que el lenguaje sea más accesible para el usuario: las ideas se pueden expresar con mayor claridad, concisión o en un estilo alternativo que algunos prefieran. El azúcar sintáctico suele ser una abreviatura para una operación común que también podría expresarse de forma alternativa y más extensa. El programador puede elegir entre la forma abreviada o la larga, pero generalmente optará por la abreviada, ya que es más corta y fácil de escribir y leer.
Por ejemplo, en el lenguaje de programación Python es posible obtener un elemento de una lista en un índice dado usando la sintaxis list_variable.__getitem__(index), pero esto se abrevia frecuentemente a , list_variable[index]que podría considerarse más simple y fácil de leer, a pesar de tener un comportamiento idéntico. De manera similar, list_variable.__setitem__(index, value)se abrevia frecuentemente a list_variable[index] = value.
Una construcción en un lenguaje es azúcar sintáctico si se puede eliminar del lenguaje sin que ello afecte a lo que el lenguaje puede hacer: la funcionalidad y el poder expresivo seguirán siendo los mismos.
Los procesadores de lenguaje, incluidos los compiladores y los analizadores estáticos , a menudo expanden las construcciones simplificadas a sus equivalentes más detallados antes de procesarlas, un proceso que a veces se denomina "descifrado".
Orígenes
El término azúcar sintáctico fue acuñado por Peter J. Landin en 1964 para describir la sintaxis superficial de un lenguaje de programación simple similar a ALGOL que se definió semánticamente en términos de las expresiones aplicativas del cálculo lambda , [ 1 ] [ 2 ] centrado en reemplazar léxicamente λ con "donde".
Lenguajes de programación posteriores, como CLU , ML y Scheme , extendieron el término para referirse a la sintaxis dentro de un lenguaje que podía definirse en términos de un núcleo de construcciones esenciales; las características convenientes de nivel superior podían "descomponerse" y descomponerse en ese subconjunto. [ 3 ] Esta es, de hecho, la práctica matemática habitual de construir a partir de primitivas.
Partiendo de la distinción de Landin entre construcciones lingüísticas esenciales y azúcar sintáctico, en 1991, Matthias Felleisen propuso una codificación del "poder expresivo" para alinearla con las "creencias ampliamente aceptadas" en la literatura. Definió "más expresivo" como la condición de que, sin las construcciones lingüísticas en cuestión, un programa tendría que ser completamente reorganizado. [ 4 ]
Ejemplos notables
- En COBOL , muchas de las palabras clave intermedias son azúcar sintáctico que opcionalmente se puede omitir. Por ejemplo, la sentencia
MOVE A B.y la sentenciaMOVE A TO B.realizan exactamente la misma función, pero la segunda aclara la acción a realizar. - En Perl , es azúcar sintáctico para . Además, cualquier instrucción puede ir seguida de una condición, por lo que es equivalente a , pero la primera se formatea de forma más natural en una sola línea.
unless(condition){...}if(notcondition){...}statementifconditionif(condition){...} - En el lenguaje C , la
a[i]notación es azúcar sintáctico para*(a + i). [ 5 ] Del mismo modo, laa->xnotación es azúcar sintáctico para acceder a los miembros usando el operador de desreferencia(*a).x. - La
usinginstrucción en C# garantiza que ciertos objetos se liberen correctamente. El compilador expande la instrucción en un bloque try-finally . [ 6 ] - C++ y C desde C23 en adelante permiten
auto x = exprcomo abreviaturadecltype(expr) x = expren C++ otypeof(expr) x = expren C. - Comprensiones de listas de Python (como para una lista de cuadrados) y decoradores (como ).
[x*xforxinrange(10)]@staticmethod - En Haskell , una cadena, entre comillas, es semánticamente equivalente a una lista de caracteres. Una extensión de lenguaje opcional, OverloadedStrings, permite que los literales de cadena produzcan también otros tipos de valores, como texto.
- En la colección de paquetes R tidyverse , la tubería , denotada por , declara que los datos (o la salida de la función) que preceden a la tubería servirán como primer argumento para la función que sigue a la tubería. [ 7 ] Por lo tanto, es equivalente a .
%>%x %>% f(y)f(x,y) - En SQL , un simple
JOINes equivalente a unINNER JOIN, este último aclara que la instrucción join es específicamente una operación de unión interna en contraposición a una operación de unión externa. Del mismo modo, se puede omitir elOUTERdeLEFT OUTER JOIN,RIGHT OUTER JOINyFULL OUTER JOIN. - El método de extensión en los lenguajes de POO en la forma
myObject.myMethod(parameter1, parameter2, parameter3)es azúcar sintáctico para llamar a una función global como . La referencia al objeto se pasa como un argumento oculto, generalmente accesible desde dentro del método como .myMethod(myObject, parameter1, parameter2, parameter3)this - Un parámetro llamado por referencia es una forma abreviada de decir que, técnicamente, se pasa un puntero como parámetro, pero sintácticamente se trata como la variable misma, para evitar la desreferenciación constante de punteros en el código dentro de la función.
- Diversos lenguajes ofrecen instrucciones de importación que permiten añadir símbolos de otro espacio de nombres al ámbito actual.
- En C++, una
usinginstrucción es un ejemplo de cómo importar un solo símbolo al ámbito, mientras que unusing namespaceespacio de nombres importa todos los símbolos de ese espacio de nombres al ámbito. - En C#, una
usinginstrucción agrega todos los símbolos de un espacio de nombres al ámbito. - En Java , un
importes un ejemplo de ello. Por ejemplo,import javax.swing.*;permite al programador hacer referencia a un objeto Swing comojavax.swing.JButtonusando solo el nombreJButton. - En Python , una
from importinstrucción importa un solo símbolo al ámbito, mientras que unafrom import *instrucción importa todos los símbolos de ese espacio de nombres al ámbito. - En Rust
use, se utiliza una instrucción para importar símbolos al ámbito.
- En C++, una
- En JavaScript , si la clave y el valor son iguales en un objeto, tienes la opción de escribirlo solo una vez. Por ejemplo,
{name: name}es equivalente a{name}. Esto se llama propiedad abreviada.- En la versión ES6 de JavaScript , las funciones flecha tienen una forma corta
(x) => x + 1, que es equivalente a la forma más larga .(x)=>{returnx+1;}
- En la versión ES6 de JavaScript , las funciones flecha tienen una forma corta
- En Scala , los tres signos de interrogación (
???) son equivalentes a . Esto es útil para marcar un lugar para código que aún no se ha escrito. [ 8 ]thrownewscala.NotImplementedError("an implementation is missing")
Crítica
Algunos programadores consideran que estas características de usabilidad sintáctica son irrelevantes o incluso frívolas. Cabe destacar que las formas sintácticas especiales hacen que un lenguaje sea menos uniforme y su especificación más compleja, y pueden causar problemas a medida que los programas se vuelven más grandes y complejos. Esta opinión está particularmente extendida en la comunidad Lisp , ya que Lisp tiene una sintaxis muy simple y regular, y la sintaxis superficial se puede modificar fácilmente. [ 9 ] Por ejemplo, Alan Perlis bromeó una vez en " Epigramas sobre programación ", en referencia a los lenguajes delimitados por corchetes , diciendo que "el azúcar sintáctico causa cáncer de punto y coma ". [ 10 ]
Términos derivados
Sal sintáctica
La metáfora se ha ampliado acuñando el término "sal sintáctica" , que indica una característica diseñada para dificultar la escritura de código deficiente. [ 11 ] Específicamente, la sal sintáctica es un obstáculo que los programadores deben superar simplemente para demostrar que saben lo que está sucediendo, en lugar de para expresar una acción del programa.
En C# , al ocultar un miembro de clase heredado, se emite una advertencia del compilador a menos que newse use la palabra clave para especificar que la ocultación es intencional. [ 12 ] Para evitar posibles errores debido a la similitud de la sintaxis de la instrucción switch con la de C o C++, C# requiere un para cada etiqueta breakno vacía de un (a menos que se use , , o ) aunque no permite la ejecución implícita . [ 13 ] (Usar y especificar la etiqueta subsiguiente produce una ejecución similar a la de C/C++ ).caseswitchgotoreturnthrowgoto
El uso de sal sintáctica puede frustrar su propósito al hacer que el código sea ilegible y, por lo tanto, empeorar su calidad ; en casos extremos, la parte esencial del código puede ser más corta que la sobrecarga introducida para satisfacer los requisitos del lenguaje.
Una alternativa al uso de la sal sintáctica es generar advertencias del compilador cuando existe una alta probabilidad de que el código sea el resultado de un error , una práctica común en los compiladores modernos de C/C++.
sacarina sintáctica
Otras extensiones son la sacarina sintáctica y el jarabe sintáctico , es decir, la sintaxis gratuita que no facilita la programación. [ 14 ] [ 15 ] [ 16 ] [ 17 ]
Tipos azucarados
Los tipos de datos con soporte sintáctico básico se denominan "tipos azucarados". [ 18 ] [ 19 ] [ 20 ] Algunos ejemplos comunes incluyen cadenas delimitadas por comillas, llaves para tipos de objetos y registros, y corchetes para matrices.
Notas
- ↑ Landin, Peter J. (1964). "La evaluación mecánica de expresiones" (PDF) . The Computer Journal . 6 (4). Computer Journal : 308–320 . doi : 10.1093/comjnl/6.4.308 . Recuperado el 21 de julio de 2014 .
- ↑ Abelson y Sussman 1996 , Capítulo 1, nota al pie 11 .
- ↑ Barbara Liskov, "Una historia de CLU", Informe técnico 561 del Laboratorio de Ciencias de la Computación del MIT (1993)
- ↑ Felleisen, Matthias (diciembre de 1991). "Sobre el poder expresivo de los lenguajes de programación" . Science of Computer Programming . 17 ( 1–3 ). Springer-Verlag: 35–75 . doi : 10.1016/0167-6423(91)90036-W . Recuperado el 19 de julio de 2014 .
- ↑ Raymond, Eric S. (11 de octubre de 1996). The New Hacker's Dictionary – 3.ª edición . MIT Press. pág. 432. ISBN 978-0-262-68092-9Consultado el 5 de agosto de 2012 .
- ↑ "using Statement (C# Reference)" . Consultado el 16 de septiembre de 2014 .
- ↑ "magrittr: Viñeta" . Consultado el 24 de diciembre de 2018 .
- ↑ "Stack Overflow: ¿Qué significa el triple signo de interrogación en Scala?" . Consultado el 23 de enero de 2024 .
- ↑ Abelson y Sussman 1996 , Capítulo 1, nota al pie 11 .
- ↑ Perlis 1982 , Epigrama #3.
- ↑ "The Jargon File - syntactic salt" . 12 de junio de 2003. Archivado del original el 12 de junio de 2003. Consultado el 19 de marzo de 2018 .
- ↑ "Nuevo modificador (Referencia de C#)" . microsoft.com . Microsoft . Consultado el 3 de agosto de 2015 .
- ↑ "switch (Referencia de C#)" . microsoft.com . Microsoft . Consultado el 3 de agosto de 2015 .
- ↑ "azúcar sintáctico" . catb.org . Consultado el 3 de agosto de 2015 .
- ↑ Boiten, Eerke A.; Möller, Bernhard (26 de junio de 2002). Matemáticas de la construcción de programas . Springer. ISBN 9783540438571Consultado el 3 de agosto de 2015 .
- ↑ Dean, Thomas (2004). Hablando con ordenadores: Exploraciones en la ciencia y la tecnología de la computación . Cambridge University Press. pág . 115. ISBN 9780521542043.
- ↑ Harrison, William; Sheard, Tim (8-10 de julio de 2002). «Matemáticas de la construcción de programas» (PDF) . Matemáticas de la construcción de programas: 6.ª Conferencia Internacional, MPC 2002, Castillo de Dagstuhl, Alemania, 8-10 de julio de 2002. Actas . Conferencia Internacional sobre Matemáticas de la Construcción de Programas. Lecture Notes in Computer Science. Vol. 2386. Castillo de Dagstuhl, Alemania: Springer Berlin Heidelberg. p. 93. doi : 10.1007/3-540-45442-X_6 . ISBN 978-3-540-43857-1. S2CID 10059915 . Archivado del original (PDF) el 31 de marzo de 2017.
- ↑ Chugh, Ravi (2013). Tipos de refinamiento anidados para JavaScript (PhD). UC San Diego.
- ↑ "Documentación de LLVM en lenguaje C" . clang.llvm.org . Consultado el 30 de junio de 2020 .
- ↑ "La vida secreta de los tipos en Swift" . medium.com/@slavapestov . 14 de julio de 2016. Consultado el 30 de junio de 2020 .
Referencias
- Abelson, Harold ; Sussman, Gerald Jay ; Sussman, Julie (1996) [1984]. Estructura e interpretación de programas informáticos . Cambridge, MA: MIT Press . ISBN 0-262-51087-1.
- Landin, Peter J. (febrero-marzo de 1965). "Una correspondencia entre ALGOL 60 y la notación Lambda de Church: partes I y II" . Communications of the ACM . 8 (2.3): 89–101 , 158–165 . doi : 10.1145/363744.363749 . S2CID 6505810 .
- Landin, Peter J. (marzo de 1965). "Programación sin imperativos: un ejemplo". UNIVAC Systems Programming Research .
- Landin, Peter J. (julio de 1965). "Eliminar las etiquetas". UNIVAC Systems Programming Research .
- Landin, Peter J. (agosto de 1965). "Una generalización de saltos y etiquetas". UNIVAC Systems Programming Research ., reimpreso en " Higher-Order and Symbolic Computation ". 11 . 1998: 125– 143. CiteSeerX 10.1.1.85.2610 .
{{cite journal}}: Para citar una revista se requiere|journal=( ayuda ) - Perlis, AJ (septiembre de 1982). «Epigramas sobre programación» . ACM SIGPLAN Notices . 17 (9). Nueva York, NY, EE. UU.: Association for Computing Machinery: 7–13 . doi : 10.1145/947955.1083808 . S2CID 20512767. Archivado del original el 17 de enero de 1999.
- sintaxis del lenguaje de programación
- jerga informática
- Código fuente
- Diseño de lenguajes de programación
- Metáforas que hacen referencia a la comida y la bebida.