* bug#17825: broken set! in iteration
@ 2014-06-21 1:25 Alírio Eyng
2014-06-21 21:19 ` Mark H Weaver
0 siblings, 1 reply; 3+ messages in thread
From: Alírio Eyng @ 2014-06-21 1:25 UTC (permalink / raw)
To: 17825
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)))
guile (GNU Guile) 2.0.11
i686-pc-linux-gnu
^ permalink raw reply [flat|nested] 3+ messages in thread
* bug#17825: broken set! in iteration
2014-06-21 1:25 bug#17825: broken set! in iteration Alírio Eyng
@ 2014-06-21 21:19 ` Mark H Weaver
2014-06-21 21:29 ` Mark H Weaver
0 siblings, 1 reply; 3+ messages in thread
From: Mark H Weaver @ 2014-06-21 21:19 UTC (permalink / raw)
To: Alírio Eyng; +Cc: 17825, request
tags 17825 notabug
close 17825
thanks
Alírio Eyng <alirioeyng@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.
So, you need to change '(()) to (list '()). Also, if you will ever
mutate the pairs in '(((3 4))), you'll need to change that as well.
Another problem is that 'map' does not specify the order in which the
procedure is applied to the elements of the input list. We have
'map-in-order', but both of those also build a list of the results,
which is not needed here.
Here, you should be using 'for-each', which guarantees the order of
iteration and does not build a list of the results.
The following code works as expected:
--8<---------------cut here---------------start------------->8---
(use-modules (srfi srfi-1))
(define D '(((3 4))))
(for-each (lambda (r)
(set! D (append D (list '())))
(display D)(newline)
(set-car! (drop D r) (car (drop D (- r 1)))))
'(1 2))
--8<---------------cut here---------------end--------------->8---
and outputs:
--8<---------------cut here---------------start------------->8---
(((3 4)) ())
(((3 4)) ((3 4)) ())
--8<---------------cut here---------------end--------------->8---
I'm closing this bug, but if you think there's still a bug here, feel
free to reopen it.
Thanks!
Mark
^ permalink raw reply [flat|nested] 3+ messages in thread
* bug#17825: broken set! in iteration
2014-06-21 21:19 ` Mark H Weaver
@ 2014-06-21 21:29 ` Mark H Weaver
0 siblings, 0 replies; 3+ messages in thread
From: Mark H Weaver @ 2014-06-21 21:29 UTC (permalink / raw)
To: Alírio Eyng; +Cc: 17825
Mark H Weaver <mhw@netris.org> writes:
> tags 17825 notabug
> close 17825
> thanks
>
> Alírio Eyng <alirioeyng@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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-06-21 21:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-21 1:25 bug#17825: broken set! in iteration Alírio Eyng
2014-06-21 21:19 ` Mark H Weaver
2014-06-21 21:29 ` Mark H Weaver
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).