2011-11-27 18 views
18

Racket'te basit okuyucu makroları oluşturmanın bir yolu var mı? Bunun gibi bir genellemeyi kastediyorum: Ne demek istediğimi açıklamak için yerleşik bir sözdizimi kullanmıştım. Bunu kullanmak istediğim şeylerden biri, clojure'ın shorthand lambda (#(+ 1 %) 5) ; => 6Roket okuyucu makroları

çoğaltılmasıdır. Bir "shorthand-lambda" makrosu tanımlamak ve "#" önekini bununla eşleştirmek çok kolay olurdu.

+0

Sen kodunda bakarak ilginizi çekebilir [afl] (https://github.com/AlexKnauth/afl) veya [curly-fn] (https://github.com/lexi-lambda/racket-curly-fn), her ikisi de okuyucuların tam uygulamalarını tanımlar shorthand lambda ifadeleri için uzantılar. –

cevap

8

Bunu nasıl yapacağınızı görmek için readtables ve reader extensions kılavuzlarına bakın. Bu reference section da yararlıdır. Readtable uzantıları, örneğinizden biraz daha karmaşıktır, ancak çok güçlüdür.

Sorununuz için, SRFI-26, Scheme için benzer bir sözdizimi sağlar ve Sam Tobin-Hochstadt, Scala'nın bunu uygulayan bir fancy app Racket makrosu yazdı. ' için

#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 
İşte

sizin basit örneği nasıl uygulanacağı var, & eşdeğer hale:

16

İşte stenografi lambda nasıl uygulanacağı var

(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

İlk örnekten (λ (c in. _) 'Içinde' c' nedir? – adrusi

+1

Okuyucu makroyu tetikleyen karakter budur, bu durumda her zaman # # # '. -readtable'] (http://pre.racket-lang.org/docs/html/reference/readtables.html#%28def._%28%28quote._~23~25kernel%29._make-readtable%29% 29). –