[racket] tutorial: exploring the boundaries of outer space

From: Danny Yoo (dyoo at cs.wpi.edu)
Date: Fri Apr 20 16:42:58 EDT 2012

Hi Brian,

I wanted to revisit this!  Reading back your comments and Eli's, I
think I see now that syntax-parameterize is not what I want, because
it doesn't respect lexical boundaries. The whole point of the 'outer'
I'm trying to define is to respect those boundaries, even as I'm
drilling holes in them.

So taking Eli's suggested patch, I think the following does what I
want, in terms of introducing an 'outer' identifier that's lexically
scoped in terms of the 'def' definition.

#lang racket
(require racket/splicing
         (for-syntax syntax/strip-context))

(define-syntax (def stx)
  (syntax-case stx ()
    [(_ (name args ...) body ...)
     (with-syntax ([outside-context stx]
                   [outer-keyword (datum->syntax stx 'outer)])
       #'(splicing-let-syntax ([outer-keyword
                                (lambda (an-stx)
                                  (syntax-case an-stx ()
                                    [(_ outer-expr)
#'outside-context #'outer-expr)]))])
            (define (name args ...)
               body ...)))]))

(define-syntax (outer stx)
  (raise-syntax-error #f "Shouldn't be used outside the context of a
def\n" stx))

In this case, I don't need to touch syntax-parameterize, though I do
need to use datum->syntax carefully to introduce the 'outer' keyword.

I modified Eli's code to use the 'replace-context' function from
syntax/strip-context, since that's the intent I want to express: I
want to take the syntax of the outer's subexpression, and replace its
lexical context with one sourced from the outside of the 'def'.

I'll hammer on it and test cases in outer.rkt and test-outer.rkt in
https://github.com/dyoo/outer-tutorial, and then revise the tutorial
to take into account your and Eli's corrections.

Thank you again!

Posted on the users mailing list.