On Apr 27, 2016, at 12:30 PM, Alex Knauth <alexan...@knauth.org> wrote:
> 
> Well, it's not even that. This doesn't work:
>   (let ()
>     (define-sli-foo)
>     (let ()
>       (invoke-sli-foo)))


Based on that, here's simpler example of why I find `syntax-local-introduce` 
confounding. 

It seems to break the #1 rule of hygienic macros — that macro-introduced 
identifiers retain their bindings from the macro-definition site — merely by 
proximity. 

Consider the examples below. The `invoke-foo` macro introduces `foo`, which, by 
the #1 rule, ought to refer to the `foo` function defined nearby. 

Example A: `invoke-foo` relies on the hygienic `foo` reference. As we would 
expect.

Example B: But when `define-sli-foo` is used next to `invoke-foo`, 
`define-sli-foo` somehow manages to rebind the `foo` identifier inside 
`invoke-foo`. 

Example C: As Alex points out, when `invoke-foo` is moved into a sub-`let`, 
hygiene is restored (even though we'd ordinarily expect `define` bindings to 
carry through).

Makes me nostalgic for the good old days of `datum->syntax` ...


;;;;;;;;;;
#lang racket

(define (foo) 'hygienic-func)

(define-syntax-rule (invoke-foo) (foo))

(define-syntax (define-sli-foo stx)
  (syntax-case stx ()
    [(_)
     (with-syntax ([sli-foo (syntax-local-introduce #'foo)])
       #`(begin
           (define (sli-foo) 'sli-func)))]))


(module* test #f
  (require rackunit)
  
  ;; example A
  (check-equal? (invoke-foo) 'hygienic-func) ; yes of course
  
  ;; example B
  (check-equal?
   (let ()
     (define-sli-foo)
     (invoke-foo)) 'sli-func) ; um, why?
  
  ;; example C
  (check-equal?
   (let ()
     (define-sli-foo)
     (let ()
       (invoke-foo))) 'hygienic-func)) ; gaah why?!?!?!?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to