The guile-2.0.9 compiler doesn't preserve the distinctness of mutable objects that are referenced in code via the read-eval (#.) facility. (I'm not mutating the code itself, only quoted objects.) The interpreter, and for comparison guile-1.8, do preserve object identity, allowing read-eval to be used to incorporate direct object references into code. Test case:
$ cat t9 (cond-expand (guile-2 (defmacro compile-time f `(eval-when (compile eval) ,@f))) (else (defmacro compile-time f `(begin ,@f)))) (compile-time (fluid-set! read-eval? #t)) (compile-time (define aaa (cons 1 2))) (set-car! '#.aaa 5) (write '#.aaa) (newline) (write '(1 . 2)) (newline) $ guile-1.8 t9 (5 . 2) (1 . 2) $ guile-2.0 --no-auto-compile t9 (5 . 2) (1 . 2) $ guile-2.0 t9 ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 ;;; or pass the --no-auto-compile argument to disable. ;;; compiling /home/zefram/usr/guile/t9 ;;; compiled /home/zefram/.cache/guile/ccache/2.0-LE-8-2.0/home/zefram/usr/guile/t9.go (5 . 2) (5 . 2) $ guile-2.0 t9 (5 . 2) (5 . 2) In the test case, the explicitly-constructed pair aaa is conflated with the pair literal (1 . 2), and so the runtime modification of aaa (which is correctly mutable) affects the literal. This issue seems closely related to the problem described at <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=11198>, wherein the compiler is entirely unable to handle code incorporating references to some kinds of object. In that case the failure mode is a compile-time error, so the problem can be worked around. The failure mode with pairs, silent misbehaviour, is a more serious problem. Between them, these problems break most of the interesting uses for read-eval, albeit only when using the compiler. Debian incarnation of this bug report: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=734157 -zefram