매크로와 일치하는 패턴을 쓰려고합니다. 나는별로 멀지 않았지만 나는 이미 혼란 스럽다. 테스트 코드는 다음과 같습니다.렉시 컬 범위 지정 및 구문 - 케이스
#!r6rs
(import (for (rnrs base (6)) run expand)
(for (rnrs syntax-case (6)) expand)
(rnrs io simple (6)))
(define-syntax matcher
(lambda (stx)
(define (parse-clauses c)
#'x)
(syntax-case stx()
((_ c ...)
(with-syntax ((body (parse-clauses #'(c ...))))
#'(lambda (x) body))))))
(write ((matcher) '(1 2 3))) (newline)
출력 할 때 출력은 (1 2 3)
입니다.
솔직히 말해서이 코드가 실패 할 것이라는 기대로이 코드를 작성했습니다. parse-clauses
에서 반환 된 구문이 정의되지 않은 기호 x
을 참조한다고 생각했습니다. 그러나 #'x
이 parse-clauses
에서 반환 된 것은 λ 식의 매개 변수 x
을 참조합니다. 나는 이유를 모른다.
이 약간의 변형은 훨씬 더 혼란 스럽습니다.
#!r6rs
(import (for (rnrs base (6)) run expand)
(for (rnrs syntax-case (6)) expand)
(rnrs io simple (6)))
(define-syntax matcher
(lambda (stx)
(define (parse-clauses c)
(let ((x 1))
#'x))
(syntax-case stx()
((_ c ...)
(with-syntax ((body (parse-clauses #'(c ...))))
#'(lambda (x) body))))))
(write ((matcher) '(1 2 3))) (newline)
이렇게하면 x: identifier used out of context in: x
오류가 발생합니다. 이 오류는 내가 이해, x
parse-clauses
에 로컬로 바인딩되어 있지만 오류가 그래서 그 범위 밖에서 참조를 사용하고 있습니다.
제가 말하고자하는 것은 두 번째 예제는 어휘 문맥이 중요하다는 것을 보여줍니다. 그러나 첫 번째 예에서는 x
에 대한 어휘 바인딩이 없으므로 관련없는 바인딩을 참조하는 것이 어떻게 끝나나요?
너무 혼란스럽지 않고 모든 설명을 환영합니다.
라켓 5.3.6을 사용하고 있습니다.