2012-04-10 13 views
8

Me gustaría crear una forma sintáctica en Racket que pueda aceptar un argumento de palabras clave, del modo en que lo hacen algunas funciones.¿Pueden las macros Racket tomar argumentos de palabra clave?

Después de haber reducido a un simple ejemplo, he intentado escribir:

(define-syntax sum-of-products 
    (syntax-rules (#:extra) 
    [(sum-of-products ([a b] ...)) 
    (+ (* a b) ...)] 
    [(sum-of-products ([a b] ...) #:extra extra) 
    (+ extra (* a b) ...)])) 

De tal manera que la siguiente sería entonces el trabajo:

(sum-of-products ([2 2] [3 3])) → 13 
(sum-of-products ([2 2] [3 3]) #:extra 5) → 18 

Desafortunadamente, Raqueta llama a esto "mala sintaxis", por lo que, obviamente, ese intento no fue correcto

¿Se puede hacer esto?

Respuesta

12

Las palabras clave en los patrones sintácticos se tratan igual que los literales como los números, por lo que no es necesario que los especifique como palabras clave. (Eso es necesario solamente para los identificadores.) Por lo tanto, las siguientes obras (nótese que me fijo el error tipográfico que tenía en el segundo ejemplo):

#lang racket 
(define-syntax sum-of-products 
    (syntax-rules() 
    [(sum-of-products ([a b] ...)) 
    (+ (* a b) ...)] 
    [(sum-of-products ([a b] ...) #:extra extra) 
    (+ extra (* a b) ...)])) 
(sum-of-products ([2 2] [3 3])) 
(sum-of-products ([2 2] [3 3]) #:extra 5) 

Ver también syntax-parse para una utilidad que puede hacer más fácil parsing keywords.

+3

En particular, la documentación 'syntax-parse' tiene toda una [sección] (http://docs.racket-lang.org/syntax/Optional_Keyword_Arguments.html) al escribir macros con argumentos de palabra clave. –

+0

(Uf, olvidé agregar ese enlace ...) –

Cuestiones relacionadas