2011-11-27 9 views
18

¿Hay alguna forma de crear macros de lector simples en Racket? Me refiero a una generalización como esta:Macros de lector de raquetas

(define-reader-syntax "'" quote) 
; finds expressions that start with "'" and wraps them in `(quote ...)` 
'(foo) ; => (quote (foo)) 
'foo ; => (quote foo) 

He utilizado una sintaxis incorporada para aclarar lo que quiero decir. Una de las cosas que me gustaría usar para replicar la abreviatura de clojure lambda (#(+ 1 %) 5) ; => 6

Parece que sería muy fácil definir una macro "taquigrafía-lambda" y asignar el prefijo "#" a eso.

+0

Usted puede estar interesado en mirar el código de [afl] (https://github.com/AlexKnauth/afl) o [curly-fn] (https://github.com/lexi-lambda/racket-curly-fn), que definen implementaciones completas del lector extensiones para expresiones abreviadas lambda. –

Respuesta

8

Consulte la entrada de la guía en readtables y reader extensions para ver cómo hacerlo. Este modelo reference section es útil también. Las extensiones leíbles son un poco más complicadas que su ejemplo, pero son muy potentes.

Para su problema específico, SRFI-26 proporciona una sintaxis similar para Scheme y Sam Tobin-Hochstadt escribió una macro de raqueta fancy app que implementa la visión de Scala sobre esto.

16

Así es como para poner en práctica su lambda abreviada:

#lang racket 

(define rt (make-readtable #f #\# 'non-terminating-macro 
          (λ (c in . _) 
          (define body (read in)) 
          `(lambda (%) ,body)))) 
(parameterize ([current-readtable rt] 
       [current-namespace (make-base-namespace)]) 
    (eval (read (open-input-string "(#(+ 1 %) 5)")))) ;; => 6 

es cómo implementar el ejemplo más sencillo aquí, haciendo & ser equivalente a ':

(define rt2 (make-readtable #f #\& #\' #f)) 

(parameterize ([current-readtable rt2] 
       [current-namespace (make-base-namespace)]) 
    (eval (read (open-input-string "&(3 4 5)")))) ;; => '(3 4 5) 
+0

En '(λ (c in. _)' Del primer ejemplo, ¿qué es 'c'? – adrusi

+1

Es el carácter que activó la macro del lector, en este caso siempre' # \ # '. Consulte la documentación de [' make -readtable'] (http://pre.racket-lang.org/docs/html/reference/readtables.html#%28def._%28%28quote._~23~25kernel%29._make-readtable%29% 29). –