On Jun 15, 2009, at 1:54 AM, Ramana Kumar wrote:
This is a combination of our approaches, which is the best for my
purposes. Issue 2 is resolved thanks to your unbound? predicate -
thanks. And I don't have to clutter the test file with lists of the
identifiers that are clearly referenced in test expressions.
That's what I thought you'd do anyways.
(define-syntax define-missing-exports
(lambda (o)
(define unbound?
(let ((empty-ctxt (car (generate-temporaries '(t)))))
(lambda (id)
(let ((unbound-id
(datum->syntax empty-ctxt (syntax->datum id))))
(free-identifier=? id unbound-id)))))
(syntax-case o ()
((_ var ...)
#`(begin .
#,(let rec ((ls #'(var ...)))
(cond
((null? ls) '())
((unbound? (car ls))
(cons
#`(define-syntax #,(car ls)
(lambda (o)
(syntax-case o ()
(_ #'(raise (symbol->string '#,(car
ls)))))))
(rec (cdr ls))))
(else (rec (cdr ls))))))))))
This is ugly! (It makes me think quasisyntax, unsyntax, and unsyntax-
splicing are a mistake.)
Do this instead:
(define-syntax if-unbound
(lambda (x)
(define unbound?
(let ([empty-ctxt (car (generate-temporaries '(t)))])
(lambda (id)
(let ([unbound-id
(datum->syntax empty-ctxt (syntax->datum id))])
(free-identifier=? id unbound-id)))))
(syntax-case x ()
[(_ (id) then else)
(if (unbound? #'id) #'then #'else)])))
(define-syntax when-unbound
(syntax-rules ()
[(_ (id) e* ...)
(if-unbound (id) (begin e* ...) (begin))]))
(define-syntax when-bound
(syntax-rules ()
[(_ (id) e* ...)
(if-unbound (id) (begin) (begin e* ...))]))
(define-syntax define-missing-exports
(syntax-rules ()
[(_ id* ...)
(begin
(when-unbound (id*)
(define-syntax id*
(lambda (_)
#'(assertion-violation 'id* "missing export"))))
...)]))
Aziz,,,