[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#17825: broken set! in iteration
From: |
Mark H Weaver |
Subject: |
bug#17825: broken set! in iteration |
Date: |
Sat, 21 Jun 2014 17:29:05 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) |
Mark H Weaver <address@hidden> writes:
> tags 17825 notabug
> close 17825
> thanks
>
> Alírio Eyng <address@hidden> 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