set!
only changes the binding of a symbol, often letting the garbage collector consume its original value. It doesn't mutate data, it rebinds a symbol. Hence things like (set! (car '(symbol symbol2)) 3)
don't work, even though the second subform evaluates to a symbol-value.
To truly mutate data in-memory, one of the forms of set-car!
, set-cdr!
, set-vector!
et cetera have to be used. These have completely different semantics and do evaluate their second sub-form, and what-ever data it evaluates to is then updated in-memory, changing all other symbol's value that share that memory with it.