Mark H Weaver <m...@netris.org> writes: > tags 17825 notabug > close 17825 > thanks > > Alírio Eyng <alirioe...@gmail.com> writes: > >> I can't see why the second code doesn't work like the first: >> >> (use-modules (srfi srfi-1)) >> (define D '(((3 4)))) >> (let ((r 1)) >> (set! D (append D '(()))) >> (display D)(newline) >> (set-car! (drop D r) (car (drop D (- r 1))))) >> (let ((r 2)) >> (set! D (append D '(()))) >> (display D)(newline) >> (set-car! (drop D r) (car (drop D (- r 1))))) >> output: >> (((3 4)) ()) >> (((3 4)) ((3 4)) ()) >> >> (use-modules (srfi srfi-1)) >> (define D '(((3 4)))) >> (map (lambda (r) >> (set! D (append D '(()))) >> (display D)(newline) >> (set-car! (drop D r) (car (drop D (- r 1))))) >> '(1 2)) >> output: >> (((3 4)) ()) >> (((3 4)) ((3 4)) ((3 4))) > > This code mutates literal lists, which is not allowed. Specifically, > this code calls 'set-car!' on pairs that come from a literal list, > namely '(()). The optimizer assumes that this will never happen, and > generates code based on that assumption.
Actually, this isn't even a question of optimization. It is simply the fact that '(()) returns the same pair every time, and the 'set-car!' mutates it to '((3 4)). In some future version of Guile, we hope to detect this error somehow, perhaps by keeping literals in read-only memory. (list '()), on the other hand, returns a freshly-allocated pair each time it is called. Mark