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.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow