On Sat, 2009-04-25 at 17:12 +0200, Michele Simionato wrote:
> On Sat, Apr 25, 2009 at 4:50 PM, Abdulaziz Ghuloum <[email protected]> wrote:
> > There might be some subtle differences in other aspects
> > of running the program, like the behavior of call/cc or even read.
> 
> Yes, I am aware of those differences. Also, in the REPL you can
> import modules at any moment, in scripts the import forms are
> the beginning.
> 
> > [PS. your definition of assert-distinct should use bound-identifier=?
> > instead of free-identifier=?, unless I misunderstood what it's used
> > for.  It is for checking duplicates in binding forms, like lambda, let
> > and letrec, right?]
> >
> 
> I will free admit that I do not understand the details of free-identifier=?
> vs bound-identifier=? and that the R6RS document looks Greek to
> me when it tries to explain the differences. What I have grossly
> understood is that I should use bound-identifier=? when I want
> to check for names that to be bound (like names in a let form)
> and free-identifier=? if I want to compare a name with an unbound
> name, like a literal identifier. But this is foggy to me, for instance
> I do not understand the difference between free-identifier=?
> and a simple function like
> 
> (define (identifier=? n1 n2)
>   (eq? (syntax->datum n1) (syntax->datum n2)))

The R6RS does do a decent job of explaining succinctly, you just need to
understand the issues.  Hopefully this helps:

(library (thing)
  (export a)
  (import (rnrs))
  (define a 1))


(import (rnrs)
        (thing)
        (rename (thing) (a r:a)))

(define-syntax show
  (syntax-rules ()
    ((_ expr)
     (begin (write 'expr) (display " => ") (write expr) (newline)))))


(define-syntax fi
  (lambda (stx)
    (syntax-case stx ()
      ((_ x)
       #`'#,(cond
              ;; If the value of the pattern variable refers to the same binding
              ;; as does the lexical scope of the `a' in the template.
              ((free-identifier=? #'x #'a) #'a)
              ;; If the value of the pattern variable is spelled the same as the
              ;; unbound `unbound' in the template.
              ((free-identifier=? #'x #'unbound) #'unbound)
              (else #'unknown))))))

(show (fi a))
(show (fi r:a))  ;; `r:a' refers to the same binding as `a' in the macro does
(show (fi unbound))  ;; unbound, so the spelling is what's compared 
(show (fi foo))
(show (let ((r:a 'shadow)) (fi r:a)))
(show (let-syntax ((a (lambda (_) 'shadow))) (fi a)))
(show (let ((unbound 'now-bound)) (fi unbound)))


(define-syntax bi
  (lambda (stx)
    (syntax-case stx ()
      ((_ x)
       #'(bi x a))  ;; a is introduced here
      ((_ x y)
       #`'(#,(bound-identifier=? #'x #'y)
           #,(free-identifier=? #'x #'y))))))

(show (bi a))  ;; same scope, different introduction
(show (bi foo foo))  ;; same introduction, same spelling
(show (bi foo bar))  ;; same introduction, different spelling
(show (bi r:a a))  ;; same scope, same introduction


(define t 'mine)

(define-syntax introduce
  (syntax-rules ()
    ((_ x)
     (let ((t 'macro-introduced))
       (list x t)))))

(show (introduce t))


$ ikarus --r6rs-script program.sps
(fi a) => a
(fi r:a) => a
(fi unbound) => unbound
(fi foo) => unknown
(let ((r:a 'shadow)) (fi r:a)) => unknown
(let-syntax ((a (lambda (_) 'shadow))) (fi a)) => unknown
(let ((unbound 'now-bound)) (fi unbound)) => unknown
(bi a) => (#f #t)
(bi foo foo) => (#t #t)
(bi foo bar) => (#f #f)
(bi r:a a) => (#f #t)
(introduce t) => (mine macro-introduced)
$ 


-- 
: Derick
----------------------------------------------------------------

Reply via email to