I am testing a wrapper macro around the racket syntax-case
macro. At step 1, it does nothing interesting and simply passes through all the parts to syntax-case
directly as follows:
#lang racket
;; definition
(define-syntax guarded-syntax-case
(lambda (x)
(syntax-case x ()
((guarded-syntax-case y (literal ...) clause ...)
#'(syntax-case y (literal ...) clause ...)
))))
;; test case
(define-syntax (binop stx)
(guarded-syntax-case stx () ; *problem site*
[(_ op n1 n2) #'(op n1 n2)]))
But this simple case fails with the following error at the empty brackets ()
labeled with problem site labeled in above code:
; ....rkt:11:27: #%app: missing procedure expression;
; probably originally (), which is an illegal empty application
; after encountering unbound identifier (which is possibly the real problem):
; guarded-syntax-case
; in: (#%app)
I couldn't figure out what could be wrong in this simple pass-through macro. The error message seems to suggest that there is a unbound variable somewhere, which I couldn't identify. I would think that the literal...
should be matched to empty.
Could someone help explain what went wrong and how to fix the macro?
The problem is that guarded-syntax-case
is not recognized as a macro in the correct phase . In particular, when you (define-syntax guarded-syntax-case...)
in your program, you define the macro guarded-syntax-case
that is available in phase 0. But forms in (define-syntax (binop stx)...)
must be in phase 1.
There are two ways to correct the mistake.
(define-syntax guarded-syntax-case...)
inside begin-for-syntax
. However, doing so would require syntax-case
and other stuff to be available in phase 2. So you need an additional (require (for-meta 2 racket/base))
. Here's the full code:#lang racket
(require (for-meta 2 racket/base))
;; definition
(begin-for-syntax
(define-syntax guarded-syntax-case
(lambda (x)
(syntax-case x ()
((guarded-syntax-case y (literal ...) clause ...)
#'(syntax-case y (literal ...) clause ...))))))
;; test case
(define-syntax (binop stx)
(guarded-syntax-case stx () ; *problem site*
[(_ op n1 n2) #'(op n1 n2)]))
(binop + 1 2) ;=> 3
guarded-syntax-case
, and then require
the (sub)module with for-syntax
. Here's the full code:#lang racket
(module lib racket
(provide guarded-syntax-case)
;; definition
(define-syntax guarded-syntax-case
(lambda (x)
(syntax-case x ()
((guarded-syntax-case y (literal ...) clause ...)
#'(syntax-case y (literal ...) clause ...))))))
(require (for-syntax 'lib))
;; test case
(define-syntax (binop stx)
(guarded-syntax-case stx () ; *problem site*
[(_ op n1 n2) #'(op n1 n2)]))
(binop + 1 2)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.