bug#16158: psyntax: bug in bound-identifier=?

2013-12-15 Thread Mark H Weaver
While reading psyntax.scm, I noticed that the definition of 'bound-id=?'
does not match the definition in "Syntax Abstraction in Scheme" by
Dybvig, Hieb, and Bruggeman.

The paper states "Two identifiers that are bound-identifier=? are also
free-identifier=?".  The following expression shows that this is not the
case in Guile 2.0:

  (let* ((x 1) (s1 #'x)
 (x 2) (s2 #'x))
(list (bound-identifier=? s1 s2)
  (free-identifier=? s1 s2)))
  => (#t #f)

Racket reports (#f #f) for the same expression.

According to the paper, two identifiers are 'bound-id=?' if and only if
they resolve to the same binding name (gensym) and have the same marks
(i.e. they were both introduced by the same macro instantiation, or
neither were introduced by a macro).  However, the implementation in
'psyntax.scm' does not compare the binding names (gensyms); it instead
compares only the symbolic names.

  Mark





bug#16158: psyntax: bug in bound-identifier=?

2013-12-15 Thread Mark H Weaver
Fixed in stable-2.0, commit 70c74b847680d3b239e591afa2e99c51a712980c

Mark





bug#16158: psyntax: bug in bound-identifier=?

2013-12-15 Thread Marco Maggi
Mark H Weaver wrote:
> While reading psyntax.scm, I noticed that the definition of 'bound-id=?'
> does not match the definition in "Syntax Abstraction in Scheme" by
> Dybvig, Hieb, and Bruggeman.
>
> The paper states "Two identifiers that are bound-identifier=? are also
> free-identifier=?".

I think you are referring to this paragraph from the paper[1] (page 12):

Twoidentifiers   thatare   bound-identifier=? are   also
free-identifier=?,  but two  identifiers that  are free-identifier=?
may not be bound-identifier=?.  An  identifier introduced by a macro
transformer may refer to the same enclosing binding as an identifier
not introduced by the transformer, but an introduced binding for one
will not capture references to the other.

> The following expression shows that this is not the case in Guile 2.0:
>
>   (let* ((x 1) (s1 #'x)
>  (x 2) (s2 #'x))
> (list (bound-identifier=? s1 s2)
>   (free-identifier=? s1 s2)))
>   => (#t #f)

  The expander in Ikarus/Vicare also returns this value.

> Racket reports (#f #f) for the same expression.

  Racket is different because its expander implements a variant of phase
separation; if the whole form is evaluated  at phase N, the "x" in "#'x"
should be searched  among the bindings at  phase N-1 (if any)  (I am not
authoritative  in  how Racket  works,  there  is always  something  that
escapes me).   Your code  works, but  when you actually  try to  use the
identifiers for something:

#!r6rs
(import (rnrs))
(define-syntax doit
  (lambda (stx)
(let* ((x 1) (s1 #'x)
   (x 2) (s2 #'x))
  #`(let ((#,s1 123))
  #,s2
(doit)

$ plt-r6rs ~/var/tmp/proof.sps
/home/marco/var/tmp/proof.sps:7:23: x: identifier used out of context
  in: x
  context...:
   /opt/racket/5.3.5/lib/racket/collects/r6rs/run.rkt: [running body]

while the  same program  works fine in  Ikarus, Vicare,  Sagittarius and
Guile (Larceny's  opinion would  be interesting,  but I  do not  have it
installed).  IMHO this program should work for Racket, too, but maybe it
refuses to  run code that "looks  wrong" (indeed, usually, in  a correct
program we do not define identifiers this way).

  I dunno how  Guile's evolution of psyntax works, but  the two #'x must
be bound-identifier=? because the following result must stand:

(define-syntax doit
  (lambda (stx)
(let* ((x 1) (s1 #'x)
   (x 2) (s2 #'x))
  #`(let ((#,s1 123))
  #,s2

(doit) => 123

  IMHO it  is an  error in  the paper.  Some  paragraphs from  the paper
preceding "the  one" have been recycled  in the R6RS document,  but this
one paragraph has not; maybe this means something.

HTH

[1] 
-- 
"Now feel the funk blast!"
Rage Against the Machine - "Calm like a bomb"