Я видел следующий код:
#lang r5rs (define ma-liste-1 (list 2 3 4 5)) (define ma-liste-2 (list 6 7 8 9)) (define (cons! e L) (set-cdr! L (cons (car L) (cdr L))) (set-car! L e)) (cons! 1 ma-liste-1) ma-liste-1 ; (list 1 2 3 4 5)
Я просто не понимаю, почему не работает следующий код:
#lang r5rs (define ma-liste-1 (list 2 3 4 5)) (define ma-liste-2 (list 6 7 8 9)) (define (cons! e L) (set-cdr! L L) (set-car! L e)) (cons! 1 ma-liste-1) ma-liste-1 ; #0=(mcons 1 #0#)
Может кто-нибудь помочь?
(set-cdr! L L)
создает ячейку cons, чья cdr ссылается на себя по кругу, в искусстве ASCII
cons
cdr
.-> ( CAR . CDR ) / / \___________/
, в то время как (set-cdr! L (cons (car L) (cdr L))) сначала восстанавливает cdr, чтобы не было круговой ссылки.
(set-cdr! L (cons (car L) (cdr L)))
Вы вынуждены сделать копию, иначе, как вы можете видеть, вы в конечном итоге мутируете в существующий список, и в итоге делаете его круглым списком (эта запись используется для таких общих структур).