schemeracketr6rs

difference between free-identifier=? and bound-identifier=?


Trying to understand free-identifier=? and bound-identifier=?. Can anyone give me equivalent code examples where using free-identifier=? would return true and using bound-identifier=? would return false.

Thanks


Solution

  • Here's an example:

    (define-syntax (compare-with-x stx)
      (syntax-case stx ()
        [(_ x-in)
         (with-syntax ([free=? (free-identifier=? #'x-in #'x)]
                       [bound=? (bound-identifier=? #'x-in #'x)])
           #'(list free=? bound=?))]))
    
    (define-syntax go
      (syntax-rules ()
        [(go) (compare-with-x x)]))
    
    (go) ;; => '(#t #f)
    

    The x introduced by go has a mark from that expansion step on it, but the x in compare-with-x doesn't, so bound-identifier=? considers them different.

    Here's another example:

    (define-syntax (compare-xs stx)
      (syntax-case stx ()
        [(_ x1 x2)
         (with-syntax ([free=? (free-identifier=? #'x1 #'x2)]
                       [bound=? (bound-identifier=? #'x1 #'x2)])
           #'(list free=? bound=?))]))
    
    (define-syntax go2
      (syntax-rules ()
        [(go2 x-in) (compare-xs x-in x)]))
    
    (go2 x) ;; => '(#t #f)
    

    Here go2 also introduces an x with a mark, whereas the x given to go2 as an argument does not have a mark. Same story.