scheme
Macros de esquema
Buscar..
Macros higiénicas y referencialmente transparentes con reglas de sintaxis.
La mayor ventaja de LISP y Scheme sobre otros lenguajes de programación convencionales es su sistema macro. A diferencia del preprocesador C y otros lenguajes de macros, las macros Scheme toman el código analizado como entrada y devuelven el código expandido como salida. Esta es una de las aplicaciones de la frase "el código es datos" de Scheme, y es lo que hace que el lenguaje sea tan poderoso.
Las macros en el esquema se crean con define-syntax , que puede definir una macro de varias maneras. El método más sencillo es utilizar syntax-rules , que utilizan la coincidencia de patrones para transformar el código de entrada en el código de salida.
Este ejemplo crea un simple for item in list y for list as item sintaxis para recorrer en bucle los elementos de una lista:
(define-syntax for
(syntax-rules (in as) ; 'in' and 'as' keywords must match in the pattern
; When the 'for' macro is called, try matching this pattern
((for element in list
body ...) ; Match one or more body expressions
; Transform the input code
(for-each (lambda (element)
body ...)
list))
; Try matching another pattern if the first fails
((for list as element
body ...)
; Use the existing macro for the transform
(for element in list
body ...))))
Estas dos macros se pueden usar de la siguiente manera, proporcionando un estilo más imperativo:
(let ((names '(Alice Bob Eve)))
(for name in names
(display "Hello ")
(display name)
(newline))
(for names as name
(display "name: ")
(display name)
(newline)))
Ejecutar el código proporcionará el resultado esperado:
Hello Alice
Hello Bob
Hello Eve
name: Alice
name: Bob
name: Eve
El error más común a tener en cuenta es no pasar los valores correctos a una macro, lo que a menudo resultará en un mensaje de error inútil que se aplica a la forma expandida en lugar de la llamada a la macro.
El for definiciones de sintaxis anteriormente no comprueban si se pasan un identificador y una lista, por lo que pasa a cualquier otro tipo resultará en un error señalando la for-each llamada en lugar de la for llamada. La depuración de esto anula el propósito de la macro, por lo que es responsabilidad del usuario colocar los controles allí e informar los errores de uso, que luego pueden detectarse en el momento de la compilación.