[plt-scheme] macro-generating macros and the bizarre properties of syntax-local-get-shadower

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Mon May 14 15:16:08 EDT 2007

Dimitris Vyzovitis skrev:
> On Mon, 14 May 2007, [ISO-8859-1] Jens Axel S�gaard wrote:
> 
>> Dimitris Vyzovitis skrev:
>>> Can someone explain this:
>>> (module bar mzscheme
>>>   (begin-for-syntax
>>>     (define (make-foos)
>>>       (let ((lst (generate-temporaries (list 'foo 'foocheck 'foov))))
>>>         (printf "temps:~a~n" (map syntax-object->datum lst))
>>>         lst)))
>>>
>>>   (define-syntax (define-foo1 stx)
>>>     (syntax-case stx ()
>>>       ((_ val)
>>>        (let-values (((foo foocheck foov) (apply values (make-foos))))
>>>          (syntax-local-introduce
>>>           #`(begin (define-syntax #,foo val)
>>>                    (define-syntax (#,foocheck stx)
>>>                      (let ((#,foov (syntax-local-value (quote-syntax #,foo))))
>>>                        (quasisyntax #,#,foov)))
>>>                    (provide #,foo #,foocheck)))))))
>> I got confused about all the unquote-syntax-es  so there is a version
>> without. Note that I'm only introducing marks on the
>> generated indentifiers.
> 
> Well, the issue is the crash with no bindings at the meta-transformer
> environment and how it goes away with syntax-local-get-shadower. Your
> version is nice and clean, but it is not always appropriate. There are
> cases where you really do need quasisyntax and unquotes; the purpose of
> the rather contrived example was to demonstrate this mystery that baffled
> me...

Well, I hadn't figured out why the above didn't work. So it was just
as much so show that the basic principle worked.

By replacing foov with 42, I found out which expression
the error stemmed from. Since the problem consists of #%datum
being unbound, I added a (datum->syntax-object #'here ...)
in order to make sure #%datum is bound.

I *think* (but I'm not sure) the reason #%datum is not
bound, is that #%datum isn't bound in the syntax-syntax-environment.
And *think* there currently are no operations to import
bindings to the syntax-syntax-environment.

(module bar mzscheme
   (begin-for-syntax
     (define (make-foos)
       (let ((lst (generate-temporaries (list 'foo 'foocheck 'foov))))
         (printf "temps:~a~n" (map syntax-object->datum lst))
         lst)))

   (define-syntax (define-foo1 stx)
     (syntax-case stx ()
       ((_ val)
        (let-values (((foo foocheck foov) (apply values (make-foos))))
          (syntax-local-introduce
           #`(begin (define-syntax #,foo val)
                    (define-syntax (#,foocheck stx)
                      (let ((#,foov
                              (datum->syntax-object
                                #'here
                                (syntax-local-value
                                 (quote-syntax #,foo)))))
                        (quasisyntax #,#,foov)))
                    (provide #,foo #,foocheck)))))))

   (define-foo1 1))
(require bar)
(foocheck2)

-- 
Jens Axel Søgaard



Posted on the users mailing list.