Thank you Ryan , for clearing my absolute misconception about free-identifier=? and bound-identifier=? .
I think hopefully I now have better understanding of free-identifier=? and bound-identifier=? . Initially it took some time to understand purpose behind bound-identifier=? , but I think I managed to get its use from your use case (hopefully). (define-syntax (new-binding-form stx) (syntax-case stx () [(_ ((x1 e1) (x2 e2) ) body) (if (and (identifier? #'e2) (bound-identifier=? #'x1 #'e2)) #'(let ([x1 e1]) (let ([x2 x1]) body)) #''failed)])) (new-binding-form ((x 2) (y x)) (+ x y)) (new-binding-form ((x 2) (y 3)) (+ x y)) For free-identifier=? , I think this is what you meant by recognising else keyword right? (define-syntax (cond2 stx) (syntax-case stx (else1) [(_ (else1 exp)) #'exp] [(_ (pred exp)) #'(when pred exp)] [(_ (pred1 exp1) (pred2 exp2) ...) (if (and (identifier? #'pred1) (free-identifier=? #'pred1 #'else1)) #'(error 'cond2 "else should be last clause...") #'(if pred1 exp1 (cond2 (pred2 exp2) ...)))])) ;;this is returns 7 (cond2 (#f 4) (else1 7)) ;;this cause error (cond2 (else1 3) (else1 4)) ;;returns 2 (let ((else1 1)) (cond2 (else1 2) (else1 3))) Thanks again for explaining in such detail and simplicity. Veer. On Sun, Apr 10, 2011 at 4:59 PM, Ryan Culpepper <ry...@ccs.neu.edu> wrote: > On 04/10/2011 12:31 AM, Veer wrote: >> >> Hello, >> >> I am unable to understand how free-identifier=? and bound-identifier=? >> works? >> >> For example suppose I have a code : >> (lambda (x y) (let ([x 2]) x)) >> >> then how do I determine if last x in the body of let is not bound by first >> parameter to lambda? , using either free-identifier=? or >> bound-identifier=? . > > You can only get answers to questions like this *after* expanding the > program. You might have a notion of the scoping rules of lambda and let, but > free-identifier=? et al don't; they can only tell you what the macro > expander has discovered about the program's binding structure. > > Before any expansion, the macro expander hasn't made any discoveries, so all > xs look alike. > > After expansion, you get something that looks like this: > (lambda (x y) (let-values ([(x) '2]) x) > so you'll have to rewrite your pattern, but now you can ask questions using > free-identifier=?. (IIRC, free-identifier=? and bound-identifier=? are > equivalent on fully-expanded programs.) > > During macro expansion, free-identifier=? and bound-identifier=? compare > identifiers based on the discoveries available at that point in time. > > (free-identifier=? x y) means if these two identifiers were turned into > references right now, would they refer to the same binding. It's how cond, > for example, recognizes the else keyword: does the identifier the macro gets > refer to the same binding as a known good reference to else. > > (bound-identifier=? x y) means if one of the identifiers were turned into a > binding occurrence and the other were turned into a reference in its scope, > eg (lambda (x) y), would the second refer to the first. This is usually only > used when you're implementing a new binding form to check for duplicates, > etc, or for really odd macros that act kind of like binding forms but don't > use Racket's core binding forms to do it. > > Ryan > _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users