[racket] scoping rules and define-for-syntax
I don't quite know where to read to understand, and to work around,
the following scoping rules.
Here's a very simple module (details not important, only the functions
being define-for-syntax'd):
(module my-new-syntax racket
(provide (except-out (all-from-out racket) lambda)
(rename-out (my-lambda lambda)))
(require (for-syntax racket))
(define-for-syntax (f3 e)
e)
(define-syntax (my-lambda e)
(syntax-case e ()
[(_ arg body) ;; _ is lambda
(with-syntax ([not-transformed-body (f3 (syntax body))])
(syntax (lambda arg not-transformed-body)))])))
If I load this module and run run
(module tester 'my-new-syntax
(define f (lambda (x) x x)))
in the definitions window I get a syntax error, whereas for
(module tester 'my-new-syntax
(define f (lambda (x) x)))
I don't. So far, so good.
However, if I change the source of my-new-syntax to be
(module my-new-syntax racket
(provide ... same as before ...)
(require ... same as before ...)
(define-for-syntax (f1 e)
(f3 e))
(define-for-syntax (f3 e)
e)
(define-syntax (my-lambda e) ... same as before ...))
and Run, I get
expand: unbound identifier in module (in phase 1, transformer
environment) in: f3
highlighting the use inside f1. If I swap the order of definitions of
f1 and f3, this works fine.
This, however, is just an illustrative simplification of my real
program, which has non-trivial mutually-referential functions. The
only solution I have is effectively
(define-for-syntax (shell e)
(define (f1 e) ...)
(define (f3 e) ...)
(f3 e))
which works, but is pretty unsatisfactory.
Shriram