I think the effect that you're seeing with a same-phase `syntax-rules` is described here:
http://www.cs.utah.edu/plt/scope-sets/general-macros.html#%28part._.Local_.Bindings_and_.Syntax_.Quoting%29 It's not as easy to find an explanation in the documentation, but the pointer at the end of https://docs.racket-lang.org/reference/syntax-model.html#%28part._stxobj-model%29 to https://docs.racket-lang.org/reference/Syntax_Quoting__quote-syntax.html#%28form._%28%28quote._~23~25kernel%29._quote-syntax%29%29 is meant to cover the detail that you're looking for. Then again, maybe nothing says that explicitly that the literals in a `syntax-rules`/`syntax-case` form are effectively `syntax-quote`d to get an identifier that can be compared in pattern matching. If you change the input #'(...) forms to (quote-syntax (...) #:local) and change the `syntax-rules` in `run-test` to (lambda (stx) (syntax-case stx () ((test_it x) (free-identifier=? #'x (quote-syntax it #:local)) #''found-it!) ((test_it other) #''(other: other)))) then you'll get the same result as the original code in Chez Scheme (or old Racket versions). Hope that helps, Matthew At Thu, 4 Jan 2018 13:38:28 -0800 (PST), Greg Rosenblatt wrote: > Hi, > > I've been experimenting with various corner cases of the macro system to > better understand the implementation. For comparison, I've also been > running the experiments in Chez Scheme. > > I found a difference of opinions when running the following two tests. The > idea is to test under what conditions syntax-rules literals are shadowed. > > ``` > #lang racket > > ;; test-it bound by let > (define (run-test) > (let ((it 22)) > (let ((test-it > (let ((it 5)) > (let ((test-it > (syntax-rules (it) > ((test_it it) 'found-it!) > ((test_it other) '(other: other))))) > (display `(0 it ,(syntax->datum (test-it #'(test-it it))))) > (newline) > (display `(0 not-it ,(syntax->datum (test-it #'(test-it > not-it))))) > (newline) > (let ((it 11)) > (display `(1 it ,(syntax->datum (test-it #'(test-it > it))))) > (newline) > (display `(1 not-it ,(syntax->datum (test-it #'(test-it > not-it))))) > (newline) > test-it))))) > (display `(2 it ,(syntax->datum (test-it #'(test-it it))))) > (newline) > (display `(2 not-it ,(syntax->datum (test-it #'(test-it not-it))))) > (newline) > (let ((it 44)) > (display `(3 it ,(syntax->datum (test-it #'(test-it it))))) > (newline) > (display `(3 not-it ,(syntax->datum (test-it #'(test-it not-it))))) > (newline))))) > > ;; test-it bound by let-syntax > (define (run-test2) > (let ((it 5)) > (let-syntax ((test-it > (syntax-rules (it) > ((test_it it) 'found-it!) > ((test_it other) '(other: other))))) > (display `(0 it ,(test-it it))) > (newline) > (display `(0 not-it ,(test-it not-it))) > (newline) > (let ((it 11)) > (display `(1 it ,(test-it it))) > (newline) > (display `(1 not-it ,(test-it not-it))) > (newline))))) > > (run-test) > (newline) > (run-test2) > ``` > > > Racket output: > (0 it (quote found-it!)) > (0 not-it (quote (other: not-it))) > (1 it (quote found-it!)) > (1 not-it (quote (other: not-it))) > (2 it (quote found-it!)) > (2 not-it (quote (other: not-it))) > (3 it (quote found-it!)) > (3 not-it (quote (other: not-it))) > > (0 it found-it!) > (0 not-it (other: not-it)) > (1 it (other: it)) > (1 not-it (other: not-it)) > > > Chez Scheme output: > (0 it 'found-it!) > (0 not-it '(other: not-it)) > (1 it '(other: it)) > (1 not-it '(other: not-it)) > (2 it '(other: it)) > (2 not-it '(other: not-it)) > (3 it '(other: it)) > (3 not-it '(other: not-it)) > > (0 it found-it!) > (0 not-it (other: not-it)) > (1 it (other: it)) > (1 not-it (other: not-it)) > > > It's interesting that the behavior under Racket depends on whether test-it > is let bound or let-syntax bound. The first block of output in either case > corresponds to let binding, while the second corresponds to let-syntax > binding. > > I've been reading https://docs.racket-lang.org/reference/syntax-model.html > and expected the Chez Scheme behavior in both cases. Racket behaved as I > expected when test-it is bound by let-syntax. But I'm pretty confused > about the normal let binding behavior under Racket. > > Can somebody explain what is happening? > > -- > 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. -- 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.