Code Review

Compare your solutions

    #|
  Упражнение 3.12

  В разделе 2.2.1 была введена следующая процедура для добавления одного списка к другому:

    (define (append x y)
      (if (null? x)
          y
          (cons (car x) (append (cdr x) y))))

  Append порождает новый список, по очереди наращивая элементы x в начало y. Процедура append! подобна
  append, но только она является не конструктором, а мутатором. Она склеивает списки вместе, изменяя
  последнюю пару x так, что ее cdr становится равным y. (Вызов append! с пустым x является ошибкой.)

    (define (append! x y)
      (set-cdr! (last-pair x) y)
      x)

  Здесь last-pair — процедура, которая возвращает последнюю пару своего аргумента:

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

  Рассмотрим последовательность действий

    (define x (list 'a 'b))
    (define y (list 'c 'd))
    (define z (append x y))

    z
    (a b c d)

    (cdr x)
    <ответ>

    (define w (append! x y))

    w
    (a b c d)

    (cdr x)
    <ответ>

  Каковы будут пропущенные <ответы>? Объясните, нарисовав стрелочные диаграммы.
|#

(#%require rackunit)

(define (append! x y)
  (set-cdr! (last-pair x) y)
  x)

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

(define x (list 'a 'b))
(define y (list 'c 'd))
(define z (append x y))

(check-equal? z '(a b c d))

(check-equal? (cdr x) '(b))

(define w (append! x y))

(check-equal? w '(a b c d))

(check-equal? (cdr x) '(b c d))

#|
          ┏━━━┳━━━┓   ┏━━━┳━━━┓        ┏━━━┳━━━┓   ┏━━━┳━━━┓
    x ───►┃ • ┃ • ╂──►┃ • ┃ ╱ ┃  y ───►┃ • ┃ • ╂──►┃ • ┃ ╱ ┃
          ┗━┿━┻━━━┛   ┗━┿━┻━━━┛        ┗━┿━┻━━━┛   ┗━┿━┻━━━┛
            ▼           ▼                ▼           ▼
          ┏━━━┓       ┏━━━┓            ┏━━━┓       ┏━━━┓
          ┃ a ┃       ┃ b ┃         ┌─►┃ c ┃    ┌─►┃ d ┃
          ┗━━━┛       ┗━━━┛         │  ┗━━━┛    │  ┗━━━┛
            ▲           ▲           │           │
          ┏━┿━┳━━━┓   ┏━┿━┳━━━┓   ┏━┿━┳━━━┓   ┏━┿━┳━━━┓
    z ───►┃ • ┃ • ╂──►┃ • ┃ • ╂──►┃ • ┃ • ╂──►┃ • ┃ ╱ ┃
          ┗━━━┻━━━┛   ┗━━━┻━━━┛   ┗━━━┻━━━┛   ┗━━━┻━━━┛

  После (append! x y):

            x                       y
            │                       │
            ▼                       ▼
          ┏━━━┳━━━┓   ┏━━━┳━━━┓   ┏━━━┳━━━┓   ┏━━━┳━━━┓
    w ───►┃ • ┃ • ╂──►┃ • ┃ • ╂──►┃ • ┃ • ╂──►┃ • ┃ ╱ ┃
          ┗━┿━┻━━━┛   ┗━┿━┻━━━┛   ┗━┿━┻━━━┛   ┗━┿━┻━━━┛
            ▼           ▼           ▼           ▼
          ┏━━━┓       ┏━━━┓       ┏━━━┓       ┏━━━┓
          ┃ a ┃       ┃ b ┃       ┃ c ┃       ┃ d ┃
          ┗━━━┛       ┗━━━┛       ┗━━━┛       ┗━━━┛
|#