Scheme - define a list against a character

I am trying to understand something interesting that happens on the diagram:

(define last-pair (lambda (x) (if (null? (cdr x)) x (last-pair (cdr x))))) 

When I defined foo this way:

 (define foo (lambda () (let ((s (list 'he 'said:))) (set-cdr! (last-pair s) (list 'ha 'ha)) s))) 

and run foo 3 times, I got:

 (he said: ha ha) (he said: ha ha) (he said: ha ha) 

But when I defined foo this way:

 (define foo (lambda () (let ((s '(he said:))) (set-cdr! (last-pair s) (list 'ha 'ha)) s))) 

and run foo 3 times, I got:

 (he said: ha ha) (he said: ha ha ha ha) (he said: ha ha ha ha ha ha) 

But why? My first thought was that we always build a new list in the first foo , but not in the second. But I did not understand how this works. The circuit defines the address in the second foo so what? Is it defined as a list also in the second foo? or symbol?

Thanks.

+4
source share
1 answer

Literal lists ( '(foo bar baz) , unlike (list 'foo 'bar 'baz) ) are not allowed to mutate . If you do this, this is a β€œmistake” (i.e., the behavior is undefined).

In this case, what you are observing is that the literal '(he said:) reused many times, with the understanding that it will not be mutated. Since you have broken this understanding, you get the strange behavior that you saw.

In contrast, when you use (list 'he 'said:) , a new list is returned each time.

+3
source

Source: https://habr.com/ru/post/1388721/


All Articles