[plt-scheme] begin-for-syntax in beginner-level

From: Danny Yoo (dyoo at cs.wpi.edu)
Date: Mon Oct 20 23:07:17 EDT 2008

I'm trying to write a macro that introduces a begin-for-syntax to
maintain compile-time registration information.  Here's a
simplification of the situation I'm seeing: imagine a 'reg' form that
remembers identifiers that we pass to it.

#lang scheme/base
(require (for-syntax scheme/base))

  (define names '()))

(define-for-syntax (register! name-stx)
  (set! names (cons name-stx names)))

;; Registers a new thing.
(define-syntax (reg stx)
  (syntax-case stx ()
    [(_ a-name)
     (syntax/loc stx
           (register! #'a-name))

;; prints out all registered things
(define-syntax (print-regs stx)
  (syntax-case stx ()
     (with-syntax ([(names ...) names])
       (syntax/loc stx
         (begin (display (quote (names ...)))

(provide reg print-regs)

When I try to use this in a program in Module language, this seems to
work ok.  Under Beginner Language, the context appears not to allow
this.  Here's the program in Beginner Language level:

(require "test.ss")
(define x 42)
(reg x)

I see the following error messsage when I try checking this for syntax.

define-values-for-syntax: illegal use (not at top-level) in:
(define-values-for-syntax () (begin (#%app register! (syntax x))

I suspect that Beginner Level is introducing a layer of syntax that
prevents me from injecting something via begin-for-syntax.  I can work
around this by using let-syntax:

(define-syntax (reg stx)
  (syntax-case stx ()
    [(_ a-name)
     (syntax/loc stx
         (let-syntax ([foo (lambda (stx-2)
                             (register! #'a-name)
                             (syntax/loc stx-2 (void)))])

but I was wondering if I'm interpreting the error message correctly,
and if my workaround is sound.

Thanks for any help!

Posted on the users mailing list.