2013-03-21 1 views
0

this page을 읽은 후. 나는 define-macro 대신 define-syntax을 사용하는 방법을 암기하기가 어렵 기 때문에 mit- 체계에서 define-macro (또는 적어도 비슷한 것을 찾아야한다.)을 구현하고 싶다. 여기 mit- 계획에서 "define-macro"를 구현하는 것이 가능합니다

내 (문제) 구현 :

(define-syntax define-macro 
    (rsc-macro-transformer 
    (let ((xfmr (lambda (macro-name macro-body) 
     (list 'define-syntax macro-name 
     (list 'rsc-macro-transformer 
      (let ((m-xfmr macro-body)) 
      (lambda (e r) 
       (apply m-xfmr (cdr e))))))))) 
     (lambda (e r) 
     (apply xfmr (cdr e)))))) 

(define-macro my-when 
    (lambda (test . branch) 
    (list 'if test (cons 'begin branch)))) 

(my-when #t 
    (begin 
    (display "True") 
    (newline))) 

그리고 REPL은 불평 :

;The object (lambda (test . branch) (list (quote if) test (cons (quote begin) branch))) is not applicable. 

나는 계획에 새로 온 사람과 잘못된 일에 대해 아무 생각이 없다, 누군가가 나를 도울 수 아웃?

답변

5

먼저, 쿼시 분법을 사용하는 방법을 배워야 매크로가 읽기 쉽습니다. 이처럼 :

(define-macro (my-when test . branch) 
    `(if ,test 
    (begin ,@branch))) 

더 심각하지만,이 syntax-rules를 사용하여 작성하는 아주 쉽게, 그리고 당신이 정말로 크게 define-macro에 그것을 선호한다.

(define-syntax-rule (my-when test branch ...) 
    (if test 
    (begin branch ...))) 

오, 이전에 define-syntax-rule을 보지 못하셨습니까? 그것은 당신이 한 절 define-syntax 매크로를 작성하는 데 사용할 수있는 간단한 매크로, 그리고 그렇게 정의되어 : define-syntax-rule를 사용하는 방법,

(define-syntax define-syntax-rule 
    (syntax-rules() 
    ((define-syntax-rule (name . pattern) template) 
    (define-syntax name 
     (syntax-rules() 
     ((name . pattern) template)))))) 

공지 사항, 간단한 매크로는 작성하기 정말 쉽게, 정말이된다.

(define-syntax-rule (let ((name value) ...) 
         expr ...) 
    ((lambda (name ...) 
    expr ...) 
    value ...)) 
+0

+1 특히 구문 규칙을 사용하는 것이 좋습니다. 그것은 위생적이며, 나중에 끔찍한 버그를 디버깅하지 않아도됩니다. –

+0

감사합니다. 전에'define-syntax-rule'에 대해 들어 보지 못했습니다. 코드를 단순화합니다. 그러나 여기에 문제가 발생했습니다. (define-syntax-rule (my-when test branch) (test (begin branch)))')를 평가하려고 시도했을 때, Unbound variable : test'라고했습니다. BTW, 내 계획 버전은 mit-scheme 9.0.1입니다. – Javran

+1

@ Javran 붙여 넣은'(define-syntax define-syntax-rule ...)을 실행 했습니까? 먼저 그렇게해야합니다. –

2

은 당신이 정말로 정의 매크로 의미를해야하는 경우에는과 같이 MIT-체계의 합리적인 근사치를 얻을 수 있습니다 : 여기에 또 다른 예입니다

(define-syntax define-macro 
    (syntax-rules() 
    ((define-macro (name . args) body ...) 
    (define-syntax name 
     (rsc-macro-transformer 
     (let ((transformer (lambda args body ...))) 
      (lambda (exp env) 
       (apply transformer (cdr exp))))))))) 

그런 정의 할 수 있습니다 내-때와 :

(define-macro (my-when test . branch) 
    `(if ,test (begin ,@branch)))