Domanda

I'm confused about destructive operations in Scheme. Let's say I have a list and some destructive procedures defined in the global environment:

(define a '(a b c))
(define (mutate-obj x)
    (set! x '(mutated)))
(define (mutate-car! x)
    (set-car! x 'mutated))
(define (mutate-cdr! x)
    (set-cdr! x 'mutated))

Then we have the following expression evaulation:

(mutate-obj! a) a => (a b c)
(mutate-car! a) a => (mutated b c)
(mutate-cdr! a) a => (mutated . mutated)

Why isn't set! having an effect on a outside its procedure when both set-car! and set-cdr! have? Why isn't the expression on the first line evaluating to (mutated)? How does all of this really work?

È stato utile?

Soluzione

The first example isn't working as you imagined. Although both the x parameter and the a global variable are pointing to the same list, when you execute (set! x '(mutated)) you simply set x (a parameter local to the procedure) to point to a different list, and a remains unchanged. It'd be different if you wrote this:

(define (mutate-obj)
  (set! a '(mutated)))

Now a gets mutated inside the procedure. The second and third procedures are modifying the contents of the a list, also pointed by x, so the change gets reflected "outside" once the procedure returns.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top