¿Se considera perjudicial el soporte de macros en un lenguaje de programación?

8

El primer abuso que viene a mi mente en C es:

#define if while 

Pero al mismo tiempo es extremadamente útil y potente cuando se usa correctamente.

Algo similar sucede con las macros Common Lisp.

¿Por qué no todos los lenguajes de programación admiten macros como esta y cuáles son las alternativas?

¿Son considerados dañinos?

OscarRyz
fuente
20
Los cuchillos son peligrosos. Una alternativa es intentar cortar cosas con cucharas.
Matt Ellen
1
@ Matt o para proporcionar buenas manijas.
OscarRyz

Respuestas:

15

Soy de la opinión de que si un lenguaje tiene macros, debe ser una parte integral y bien planificada del lenguaje y no del compilador .

Ejemplo, el sistema macro de Lisp es una característica de lenguaje integrado muy potente y está sujeta a todas las reglas y regulaciones de Lisp.

Contraejemplo, el sistema macro C / C ++ está separado del lenguaje y está integrado en el compilador. El resultado es que no está limitado a las restricciones de su idioma y puede crear código no válido y redefinir palabras clave específicas del idioma.

Al final del día, hay varios idiomas que no tienen función de macro, pero no se echan de menos esas características. Todo depende de cuán expresivo sea un lenguaje y de si tiene enfoques alternativos para la metaprogramación. La metaprogramación es solo una forma de garantizar que cuando haces X, X se hace de la misma manera en toda la aplicación.

Berin Loritsch
fuente
44
Peor aún, el preprocesador C ni siquiera forma parte del compilador.
1
¿Cuál es la diferencia que está tratando de establecer aquí entre "el lenguaje" y "el compilador"? El sistema macro de C se define en el estándar de lenguaje, las macros de Lisp son, de hecho, expandidas por el compilador de Lisp, y cualquier implementación de lenguaje se define, cuando todo está dicho y hecho, por el compilador y las bibliotecas estándar. Por lo tanto, la frase "separada del lenguaje e integrada en el compilador" no tiene sentido. ¿Quizás la distinción que está buscando es que las macros C se implementan en el front-end del compilador y las macros Lisp en el back-end?
Mason Wheeler
La distinción tiene que ver con la consistencia del lenguaje. Piénsalo de esta manera, estás planeando ir a un país extranjero y tienes que aprender a hablar francés para ir a lugares y comprar comida. Cuando se trata de aduanas, también preferiría aprender sueco o simplemente francés. Las macros del precompilador C son sintácticamente y gramaticalmente diferentes que el estándar C. El desafío cognitivo es descubrir qué hará ese otro lenguaje en su programa C estándar. En algunos casos es fácil, pero he visto frases de código completo como una definición de macro. Ahora depúralo.
Berin Loritsch
8

Las macros C y las macros Lisp son completamente diferentes. Las macros C se expanden mediante la sustitución de cadenas antes de que se realice cualquier otro procesamiento. Las macros de Lisp se expanden después de que el texto de entrada se haya analizado en un árbol de sintaxis 1 , y pueden usar todo el lenguaje durante la expansión. Con las macros Lisp, no solo puede hacer cosas estúpidas #define begin {, sino que también puede definir sus propias estructuras de control e incluso rellenar matrices en tiempo de compilación utilizando el código que desee.

Una razón para no incluir macros es que cualquier cosa más complicada que la simple sustitución de cadenas puede ser muy difícil de trabajar en lenguajes con sintaxis de estilo C. Otra queja sobre las macros es que pueden hacer que el código sea más difícil de leer, lo que puede ser cierto si no se implementa con habilidad. Las macros Lisp bien escritas pueden hacer que el código sea más fácil de leer.

1 a excepción de las macros de lectura, que se expanden durante el proceso de creación del árbol de sintaxis.

Larry Coleman
fuente
2

No creo que haya una razón específica por la que no sean compatibles en algunos idiomas, igual que por qué algunos distinguen entre mayúsculas y minúsculas y otros no. Generalmente no hay una razón real, solo una decisión que se tomó.

PERO la razón por la que no están incluidos definitivamente no es la seguridad. los

#define X Y

La declaración cambia todas las X a Y en tiempo de compilación. Si puede cambiar las declaraciones #define, simplemente podría copiar / reemplazar la fuente que estaba interesado en cambiar y compilar nuevamente.

Mike M.
fuente