You should not do destructive operations on literal data in Scheme (emphasis mine): R5RS 3.4 Storage Model
In many systems it is desirable for constants... to reside in
read-only-memory.... In such systems literal constants and the strings
returned by symbol->string
are immutable objects, while all objects
created by the other procedures listed in this report are mutable. It
is an error to attempt to store a new value into a location that is
denoted by an immutable object.
But there is another fundamental problem with the posted code. The MIT Scheme Reference Manual says of the procedures delq!
, delv!
, and delete!
:
Returns a list consisting of the top-level elements of list with all
entries equal to element removed.
This does not say that the original list is modified to the desired state; it says the the procedures return a list that has been modified to the desired state. The manual goes on to suggest:
Because the result may not be eq?
to list, it is desirable to do
something like (set! x (delete! x))
.
You may wonder why you would use a destructive operation at all when you still have to use set!
anyway. The non-destructive procedures del
, delv
, and delete
return freshly allocated copies of the original list with the appropriate removals. These allocations have a cost which the destructive operations avoid.
The posted code can be amended to avoid using a list literal and to use set!
:
1 ]=> (define ls (list 1 2 0 5))
;Value: ls
1 ]=> ls
;Value: (1 2 0 5)
1 ]=> (for-each (lambda (n) (set! ls (delq! n ls))) '(0 1 5))
;Unspecified return value
1 ]=> ls
;Value: (2)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…