2011-11-27 4 views
18

라켓에서 간단한 판독기 매크로를 만들 수있는 방법이 있습니까? 나는 다음과 같은 일반화를 의미합니다 :라켓 판독기 매크로

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

나는 무엇을 의미하는지 명확히하기 위해 내장 구문을 사용했습니다. 내가 이것을 사용하고자하는 것들 중 하나는 clojure의 약식 람다를 복제하는 것입니다. (#(+ 1 %) 5) ; => 6

"속기 - 람다"매크로를 정의하고 "#"접두어를 매핑하는 것이 매우 쉬울 것 같습니다.

+0

당신의 코드를 찾고에 관심이있을 수 있습니다 [afl] (https://github.com/AlexKnauth/afl) 또는 [curly-fn] (https://github.com/lexi-lambda/racket-curly-fn). 두 가지 모두 독자의 완전한 구현을 정의합니다. 약식 람다 식 확장. –

답변

8

readtablesreader extensions의 안내 항목을 살펴보고이를 수행하는 방법을 확인하십시오. 이 reference section도 유용합니다. 읽을 수있는 확장 기능은 예제보다 약간 복잡하지만 매우 강력합니다.

특정 문제의 경우 SRFI-26은 Scheme과 Sam에 대해 비슷한 구문을 제공합니다. Tobin-Hochstadt는 Scala가 이것을 수행하는 fancy app 라켓 매크로를 작성했습니다. '

#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 
다음

당신의 간단한 예를 구현하는 방법은, &가 동등하게 :

16

은 여기 속기 람다를 구현하는 방법은

(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

첫 번째 예제에서'(λ (c in. _)'에'c'가 무엇입니까? – adrusi

+1

독자 매크로를 트리거 한 문자입니다.이 경우 항상'# \ #'입니다. ['make -readtable'] (http://pre.racket-lang.org/docs/html/reference/readtables.html#%28def._%28%28quote._~23~25kernel%29._make-readtable%29% 29). –