[plt-scheme] Recognising identifiers bound with a certain macro

From: Robby Findler (robby at cs.uchicago.edu)
Date: Fri Feb 8 11:23:25 EST 2008

Oh, right. You need to explicitly bind the identifier `a' to a macro
that has whatever compile-time information you need in the sql macro.
In this case, maybe all you need is the name of the identifier that
has the real binding? If so, your code would look something like this:

#lang scheme

(define-syntax (def stx)
  (syntax-case stx ()
    [(_ id exp)
     #'(begin
         (define secret-binding exp)
         (define-syntax id #'secret-binding))]))

(define-syntax (use stx)
  (syntax-case stx ()
    [(_ id)
     (syntax-local-value #'id)]))

(def a 1)
(use a)

To do a better job with error messages you would want to bind `a' to a
transformer that signals a syntax error. There are a number of ways to
do this. Here's one (you can also bind it to a struct procedure if
that works better):

#lang scheme

(define-syntax (def stx)
  (syntax-case stx ()
    [(_ id exp)
     #'(begin
         (define secret-binding exp)
         (define-syntax id
           (case-lambda
             [(stx) (raise-syntax-error #f "used variable out of context" stx)]
             [() #'secret-binding])))]))

(define-syntax (use stx)
  (syntax-case stx ()
    [(_ id)
     ((syntax-local-value #'id))]))

(def a 1)
(use a)
a

hth,
Robby

On Feb 8, 2008 10:19 AM, Dave Gurnell <d.j.gurnell at gmail.com> wrote:
>
> Hmmm... I must be doing it wrong. Here's a stripped down version of my "sql"
> macro:
>
>
>    (define-syntax (sql stx)
>       (syntax-case stx ()
>         [(_ id)
>          (identifier? #'id)
>          (let ([decl (syntax-local-value #'id)])
>            (if (syntax-property decl sql-alias-key)
>              #'id
>              (raise-syntax-error #f "Not an SQL alias." stx #'id)))]))
>
> If I try this with the test-code:
>
>     (define-alias a 1)
>
>     (sql a)
>
> I get:
>
>
>     syntax-local-value: not defined as syntax:
>     #<syntax:/Users/dave/scheme/alias-test.ss:36:5>
>
> where 36:5 is the position of the "a" in "(sql a)".
>
> -- Dave
>
>
> syntax-local-value?
>
> Robby
>
> On Feb 8, 2008 7:51 AM, Dave Gurnell <d.j.gurnell at gmail.com> wrote:
> Hi all,
>
> I have a macro, "define-alias", that I'm using to define table aliases in a
> Scheme wrapper for SQL:
>
>     ; Define "a" as an alias for the "People" table:
>     (define-alias a People)
>
>     ; Use "a" in a query:
>     (sql (select #:from a ...))
>
> In my "sql" macro, I'd like to be able to distinguish between identifiers
> bound with "define-alias" and other identifiers bound with other forms. My
> current approach is to use a syntax property to uniquely mark aliases:
>
>     (define-for-syntax sql-alias-key (gensym 'sql-alias-key))
>
>
>     (define-syntax (define-alias stx)
>       (syntax-case stx ()
>         [(_ id val)
>          (identifier? #'id)
>          (with-syntax ([id (syntax-property #'id sql-alias-key #t)])
>            #'(define id val)))]))
>
> This all seems to do what I want, but I can't work out how to get from the
> identifier in the "sql" macro back to the binding identifier in the
> "define-alias".
>
> Can anyone provide the missing link (or perhaps syntax properties aren't the
> right tool for the job)?
>
> Many thanks,
>
> -- Dave
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
>
>
>
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
>


Posted on the users mailing list.