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"