2011-11-27 3 views
18

C'è un modo per rendere semplici macro lettore in Racket. Intendo una generalizzazione come questa:Macro lettore racket

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

Ho usato una sintassi integrata per chiarire cosa intendo. Una delle cose che mi piacerebbe usare per questo è replicare la stenografia di clojure lambda (#(+ 1 %) 5) ; => 6

Sembra che sarebbe molto semplice definire una macro "shorthand-lambda" e mappare il prefisso "#" a quello.

+0

Potreste essere interessati a guardare il codice per [afl] (https://github.com/AlexKnauth/afl) o [curly-fn] (https://github.com/lexi-lambda/racket-curly-fn), entrambi i quali definiscono le implementazioni complete del lettore estensioni per espressioni lambda stenografiche. –

risposta

8

Vedere la voce della guida su readtables e reader extensions per vedere come procedere. Questo reference section è anche utile. Le estensioni readtable sono un po 'più complicate del tuo esempio, ma sono molto potenti.

Per il tuo problema specifico, SRFI-26 fornisce una sintassi simile per Scheme e Sam Tobin-Hochstadt ha scritto una macro Racchetta fancy app che implementa la versione di Scala su questo.

16

Ecco come implementare il vostro lambda scorciatoia:

#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 

Ecco come implementare il vostro esempio più semplice, facendo & essere 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

In '(λ (c in. _)' Dal primo esempio, cos'è 'c'? – adrusi

+1

È il carattere che ha attivato la macro del lettore, in questo caso sempre' # \ #. Vedere la documentazione per ['make -readtable'] (http://pre.racket-lang.org/docs/html/reference/readtables.html#%28def._%28%28quote._~23~25kernel%29._make-readtable%29% 29). –