A question about free-identifier=?

I am learning Racket macro. I have a question about free-identifier=?.

Why the following code return #t?

(free-identifier=? #'car (let ([car 8]) #'car)) 
;; #t

Does the #'car under the let access the same binding?

Thanks.

1 Like

Because #'car doesn't refer to car 8 binding

(free-identifier=? #'car (let ([car 8]) #'car)) 

This program is just

(free-identifier=? #'car #'car) 

#'car will refer to (define-for-syntax car ...)

I am watching the video from CS294: Program Synthesis for Everyone. In the screencast of Language implementation (II). The lecturer said those two #'car are not equal.

I am confused about using syntax objects in normal code. Following the lecturer, syntax objects contain source code location and lexical binding information. Does it mean that it can be used in normal code?

For example,

(free-identifier=? #'car (let ([car 8]) #'car)) 

Can the rightmost #'car have lexical binding information of car 8?

PS. I just upload the video to youtube (see 4:12). If there is some license issue, I can delete it.

That's the behavior of the old macro expander. See https://www.cs.utah.edu/plt/scope-sets/general-macros.html for details.

1 Like

Thanks.

It seems that the scope of rightmost #'car in (free-identifier=? #'car (let ([car 8]) #'car)) has been discarded in new version. I am not clear why to do this though.

The old behavior seems to be regained by (quote-syntax car #:local).

(free-identifier=? (quote-syntax car #:local) (let ([car 8]) (quote-syntax car #:local))) 
;; #f

Does this mean that #:local is just to be compatible with the old version?

I also noticed that the program in the question returns #f in Chez Scheme 9.5.2,

(free-identifier=? #'car (let ([car 8]) #'car))
;; #f

To understand the difference, it seems necessary to read the entire history of Racke/Scheme macro system.

In the Racket lecture video 19:00, Matthew Flatt said that

free-identifier=? when they have the same biggest subset match for our binding somewhere else.

bound-identifier=? is simply they have the same sets.

For the example of the question,

(free-identifier=? #'car (let ([car 8]) #'car)) 

These two #'car ought to have the same biggest subset, but they have different scope sets. (The left #'car has color pink, and the right #'car has pink and blue.)

However,

(bound-identifier=? #'car (let ([car 8]) #'car))
;; #t

still returns #t. Perhaps due to discard?