unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* perplexing syntax-rules bug
@ 2014-12-19 20:14 Wette, Matthew R (3441)
  2014-12-19 23:11 ` Panicz Maciej Godek
  2014-12-20  7:39 ` Marco Maggi
  0 siblings, 2 replies; 7+ messages in thread
From: Wette, Matthew R (3441) @ 2014-12-19 20:14 UTC (permalink / raw)
  To: guile-user@gnu.org

[-- Attachment #1: Type: text/plain, Size: 747 bytes --]

Sorry to bug,  I can't figure out why "sval" in the second evaluation of "sect" is bound to the "sval" from the first evaluation of "sect".   Anyone understand?   This is guile 2.0.11.    -- Matt


;; bug_syntax.scm


(define-syntax sect

  (syntax-rules ()

    ((sect <name> <expr> ...)

     (let ((sval '((name . <name>) (title . #f))))

       (format #t "new sect: ~a\n" (quote <name>))

       (format #t "    sval= ~a\n\n" sval)

       (assq-set! sval 'title "ABC")

       (values)))))


(sect one (title "Section One"))

(sect two (title "Section Two"))

> (load "bug_syntax.scm")


new sect: one

    sval= ((name . one) (title . #f))


new sect: two

    sval= ((name . two) (title . ABC))




[-- Attachment #2: Type: text/html, Size: 2789 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: perplexing syntax-rules bug
  2014-12-19 20:14 perplexing syntax-rules bug Wette, Matthew R (3441)
@ 2014-12-19 23:11 ` Panicz Maciej Godek
  2014-12-20  7:39 ` Marco Maggi
  1 sibling, 0 replies; 7+ messages in thread
From: Panicz Maciej Godek @ 2014-12-19 23:11 UTC (permalink / raw)
  To: Wette, Matthew R (3441); +Cc: guile-user@gnu.org

[-- Attachment #1: Type: text/plain, Size: 1779 bytes --]

It doesn't seem to be a bug in syntax-rules. It seems to appear whenever
two consecutive let forms are used with an assoc list argument which starts
with identical elements:

(begin
  (let ((l '((a . X)(b . Y)(c . 7))))
    (assoc-set! l 'b 'Z))
  (let ((l '((a . X)(b . Y))))
    l))
===> ((a . X) (b . Z))

It is likely that the compiler assumes that both lists can be represented
using the same storage, because it doesn't notice that the first object
gets mutated.

This qualifies for a serious bug report, but if you wish to get a quick
workaround, you can do it like this:

(define-syntax sect

  (syntax-rules ()

    ((sect <name> <expr> ...)

     (let* ((sval* '(skip ((name . <name>) (title . #f))))

               (sval (cdr sval*)))

       (format #t "new sect: ~a\n" (quote <name>))

       (format #t "    sval= ~a\n\n" sval)

       (assq-set! sval 'title "ABC")

       (values)))))

Thanks&regards

2014-12-19 21:14 GMT+01:00 Wette, Matthew R (3441) <
matthew.r.wette@jpl.nasa.gov>:

>  Sorry to bug,  I can't figure out why "sval" in the second evaluation of
> "sect" is bound to the "sval" from the first evaluation of "sect".   Anyone
> understand?   This is guile 2.0.11.    -- Matt
>
>  ;; bug_syntax.scm
>
>
>  (define-syntax sect
>
>   (syntax-rules ()
>
>     ((sect <name> <expr> ...)
>
>      (let ((sval '((name . <name>) (title . #f))))
>
>        (format #t "new sect: ~a\n" (quote <name>))
>
>        (format #t "    sval= ~a\n\n" sval)
>
>        (assq-set! sval 'title "ABC")
>
>        (values)))))
>
>
>  (sect one (title "Section One"))
>
> (sect two (title "Section Two"))
>
>  > (load "bug_syntax.scm")
>
>  new sect: one
>
>     sval= ((name . one) (title . #f))
>
>
>  new sect: two
>
>     sval= ((name . two) (title . ABC))
>
>
>
>
>

[-- Attachment #2: Type: text/html, Size: 4825 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: perplexing syntax-rules bug
  2014-12-19 20:14 perplexing syntax-rules bug Wette, Matthew R (3441)
  2014-12-19 23:11 ` Panicz Maciej Godek
@ 2014-12-20  7:39 ` Marco Maggi
  2014-12-20 10:29   ` Thien-Thi Nguyen
                     ` (2 more replies)
  1 sibling, 3 replies; 7+ messages in thread
From: Marco Maggi @ 2014-12-20  7:39 UTC (permalink / raw)
  To: Wette, Matthew R (3441); +Cc: guile-user@gnu.org

Wette, Matthew R (3441) wrote:

> Sorry to bug, I can't figure out why "sval" in the second evaluation
> of "sect" is bound to the "sval" from the first evaluation of "sect".
> Anyone understand? This is guile 2.0.11. -- Matt

(define-syntax sect
  (syntax-rules ()
    ((sect <name> <expr> ...)
     (let ((sval '((name . <name>) (title . #f))))
       (format #t "new sect: ~a\n" (quote <name>))
       (format #t " sval= ~a\n\n" sval)
       (assq-set! sval 'title "ABC")
       (values)))))

The  problem  is  that  ASSQ-SET!  mutates the  result  of  the  literal
expression:

   '((name . <name>) (title . #f))

this problem is not related to SYNTAX-RULES.  The form:

   '((name . <name>) (title . #f))

is a  "literal expression", it  is an  expression that evaluates  to the
datum:

   ((name . <name>) (title . #f))

every time  the literal expression  is evaluated, the returned  value is
*the* *same* datum; we can think of  it as a value that is hard-coded in
the program.  Mutating  a hard-coded value leads  to undefined behaviour
in (almost?) all the Scheme implementations.  Given that they must never
be mutated,  some Scheme implementations recognise  multiple datums that
are equal  and just store  one instance of  them (to save  memory); this
happens especially when the code  is compiled rather than interpreted or
evaluated at the REPL.

  In  an ideal  Scheme implementation:  such literal  expressions should
generate  values that  are marked  as immutable,  so that  attempting to
mutate them raises  an exception; this requires  a Scheme implementation
that,  for  every  object  type, can  distinguish  between  mutable  and
immutable instances.  This marking would consume memory or precious bits
in tagged pointers, so not all the Scheme implementations do it.

  To solve the problem you have to replace:

   '((name . <name>) (title . #f))

with:

   (list (cons 'name <name>) (cons 'title #f))

which  is an  expression  returning  a newly  allocated  alist at  every
evaluation (by  definition, LIST and  CONS return newly  allocated lists
and pairs every time).

HTH
-- 
"Now feel the funk blast!"
Rage Against the Machine - "Calm like a bomb"



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: perplexing syntax-rules bug
  2014-12-20  7:39 ` Marco Maggi
@ 2014-12-20 10:29   ` Thien-Thi Nguyen
  2014-12-20 14:37   ` Wette, Matthew R (3441)
  2014-12-20 15:02   ` Panicz Maciej Godek
  2 siblings, 0 replies; 7+ messages in thread
From: Thien-Thi Nguyen @ 2014-12-20 10:29 UTC (permalink / raw)
  To: guile-user

[-- Attachment #1: Type: text/plain, Size: 654 bytes --]

() Marco Maggi <marco.maggi-ipsu@poste.it>
() Sat, 20 Dec 2014 08:39:00 +0100

   The problem is that ASSQ-SET! mutates the result of the
   literal expression:

      '((name . <name>) (title . #f))

   this problem is not related to SYNTAX-RULES.

Right.  See also this spew:

 http://lists.gnu.org/archive/html/help-gnu-emacs/2014-11/msg00025.html

For what is a binding but a stashed hash, pre-cached?  :-D

-- 
Thien-Thi Nguyen
   GPG key: 4C807502
   (if you're human and you know it)
      read my lisp: (responsep (questions 'technical)
                               (not (via 'mailing-list)))
                     => nil

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: perplexing syntax-rules bug
  2014-12-20  7:39 ` Marco Maggi
  2014-12-20 10:29   ` Thien-Thi Nguyen
@ 2014-12-20 14:37   ` Wette, Matthew R (3441)
  2014-12-20 15:02     ` Wette, Matthew R (3441)
  2014-12-20 15:02   ` Panicz Maciej Godek
  2 siblings, 1 reply; 7+ messages in thread
From: Wette, Matthew R (3441) @ 2014-12-20 14:37 UTC (permalink / raw)
  To: guile-user@gnu.org


On Dec 19, 2014, at 11:39 PM, Marco Maggi <marco.maggi-ipsu@poste.it> wrote:

> Wette, Matthew R (3441) wrote:
> 
>> Sorry to bug, I can't figure out why "sval" in the second evaluation
>> of "sect" is bound to the "sval" from the first evaluation of "sect".
>> Anyone understand? This is guile 2.0.11. -- Matt
> 
> (define-syntax sect
>  (syntax-rules ()
>    ((sect <name> <expr> ...)
>     (let ((sval '((name . <name>) (title . #f))))
>       (format #t "new sect: ~a\n" (quote <name>))
>       (format #t " sval= ~a\n\n" sval)
>       (assq-set! sval 'title "ABC")
>       (values)))))
> 
> The  problem  is  that  ASSQ-SET!  mutates the  result  of  the  literal
> expression:
> 
>   '((name . <name>) (title . #f))
> 
> 
>  To solve the problem you have to replace:
> 
>   '((name . <name>) (title . #f))
> 
> with:
> 
>   (list (cons 'name <name>) (cons 'title #f))
> 

OK.  Thanks.   I'm guessing list-copy would be another option: (sval (list-copy '((a . 1) (b . 2)))

Matt




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: perplexing syntax-rules bug
  2014-12-20 14:37   ` Wette, Matthew R (3441)
@ 2014-12-20 15:02     ` Wette, Matthew R (3441)
  0 siblings, 0 replies; 7+ messages in thread
From: Wette, Matthew R (3441) @ 2014-12-20 15:02 UTC (permalink / raw)
  To: Wette, Matthew R (3441); +Cc: guile-user@gnu.org

[-- Attachment #1: Type: text/plain, Size: 288 bytes --]


On Dec 20, 2014, at 6:37 AM, Matt wrote:

 (list (cons 'name <name>) (cons 'title #f))


OK.  Thanks.   I'm guessing list-copy would be another option: (sval (list-copy '((a . 1) (b . 2)))

 No.  need to use alist-copy from (srfi srfi-1)  (or (map list-copy '((a . 1) (b . 2)))

[-- Attachment #2: Type: text/html, Size: 1001 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: perplexing syntax-rules bug
  2014-12-20  7:39 ` Marco Maggi
  2014-12-20 10:29   ` Thien-Thi Nguyen
  2014-12-20 14:37   ` Wette, Matthew R (3441)
@ 2014-12-20 15:02   ` Panicz Maciej Godek
  2 siblings, 0 replies; 7+ messages in thread
From: Panicz Maciej Godek @ 2014-12-20 15:02 UTC (permalink / raw)
  To: Marco Maggi; +Cc: guile-user@gnu.org, Wette, Matthew R (3441)

[-- Attachment #1: Type: text/plain, Size: 1484 bytes --]

2014-12-20 8:39 GMT+01:00 Marco Maggi <marco.maggi-ipsu@poste.it>:
>
>
> The  problem  is  that  ASSQ-SET!  mutates the  result  of  the  literal
> expression:
>
>    '((name . <name>) (title . #f))
>
> this problem is not related to SYNTAX-RULES.  The form:
>
>    '((name . <name>) (title . #f))
>
> is a  "literal expression", it  is an  expression that evaluates  to the
> datum:
>
>    ((name . <name>) (title . #f))


To be precise, in the particular context of the macro definition, <name> is
a macro parameter, so the assoc is not a literal, but a form that will get
expanded to a literal during macro expansion. In particular, it should get
expanded to

'((name . one) (title . #f))

from the first usage, and

'((name . two) (title . #f))

from the second usage.

By the way, I don't know guile internals, but I think the optimization
(i.e. the assumption that both literal objects can be considered a single
object) happens during compilation:

if you evaluate the form

(begin

  (sect one (title "Section One"))

  (sect two (title "Section Two")))

then you'll get the aforementioned unexpected behaviour, but if you
evaluate each macro separately, everything will remain to behave properly.

So I don't think that any additional bit would be needed to mark whether an
object is mutable or immutable: the compiler could check if any mutating
procedure is called on an object before it considers it to be eq? with
another equal? object from the context of an expression.

[-- Attachment #2: Type: text/html, Size: 2546 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-12-20 15:02 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-19 20:14 perplexing syntax-rules bug Wette, Matthew R (3441)
2014-12-19 23:11 ` Panicz Maciej Godek
2014-12-20  7:39 ` Marco Maggi
2014-12-20 10:29   ` Thien-Thi Nguyen
2014-12-20 14:37   ` Wette, Matthew R (3441)
2014-12-20 15:02     ` Wette, Matthew R (3441)
2014-12-20 15:02   ` Panicz Maciej Godek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).