Ricerca…


Macro igieniche e referenzialmente trasparenti con regole di sintassi

Il maggior vantaggio di LISP e Scheme rispetto ad altri linguaggi di programmazione tradizionali è il loro sistema macro. A differenza del preprocessore C e di altri linguaggi macro, le macro Scheme prendono il codice analizzato come input e restituiscono il codice espanso come output. Questa è una delle applicazioni della frase "codice è dati" di Scheme, ed è ciò che rende il linguaggio così potente.

Le macro in Scheme sono create con la define-syntax , che può definire una macro in un certo numero di modi. Il metodo più semplice consiste nell'utilizzare le syntax-rules , che utilizzano la corrispondenza del modello per trasformare il codice di input nel codice di output.

Questo esempio crea un for item in list semplice for item in list e for list as item sintassi for list as item per il loop sugli elementi di un elenco:

(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 ...))))

Questi due macro possono quindi essere utilizzati come segue, fornendo uno stile più imperativo:

(let ((names '(Alice Bob Eve)))
  (for name in names
    (display "Hello ")
    (display name)
    (newline))
  (for names as name
    (display "name: ")
    (display name)
    (newline)))

L'esecuzione del codice fornirà l'output previsto:

Hello Alice
Hello Bob
Hello Eve
name: Alice
name: Bob
name: Eve

L'errore più comune a cui prestare attenzione non è il passaggio dei valori corretti a una macro, che spesso si tradurrà in un messaggio di errore inutile che si applica al modulo espanso anziché alla chiamata macro.

Il for definizione della sintassi sopra non controllare se sono passati un identificatore e una lista, in modo da passare qualsiasi altro tipo si tradurrà in un errore che punta al for-each chiamata invece della for chiamata. Il debugging elimina lo scopo della macro, quindi spetta all'utente inserire i controlli e segnalare errori di utilizzo, che possono essere rilevati in fase di compilazione.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow