* 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®ards
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).