Code Review

Compare your solutions

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

  В разделе 3.2.3 мы видели, как модель с окружениями описывает поведение процедур, обладающих внутренним
  состоянием. Теперь мы рассмотрели, как работают локальные определения. Типичная процедура с передачей
  сообщений пользуется и тем, и другим. Рассмотрим процедуру моделирования банковского счета из раздела
  3.1.1:

    (define (make-account balance)
      (define (withdraw amount)
        (if (>= balance amount)
            (begin (set! balance (- balance amount))
              balance)
            "Insufficient funds"))
      (define (deposit amount)
        (set! balance (+ balance amount))
        balance)
      (define (dispatch m)
        (cond ((eq? m 'withdraw) withdraw)
              ((eq? m 'deposit) deposit)
              (else (error "Unknown request -- MAKE-ACCOUNT"
                           m))))

      dispatch)

  Покажите, какая структура окружений создается последовательностью действий

    (define acc (make-account 50))

    ((acc 'deposit) 40)
    90

    ((acc 'withdraw) 60)
    30

  Где хранится внутреннее состояние acc? Предположим, что мы определяем еще один счет

    (define acc2 (make-account 100))

  Каким образом удается не смешивать внутренние состояния двух счетов? Какие части структуры окружений
  общие у acc и acc2?
|#

#|
  Процедурные объекты в глобальном кадре окружения для (define acc (make-account 50)):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
     Глобальное ┃ ...                     ┃
    ───────────►┃ acc ─────────┐          ┃
      окружение┌╂ make-account │          ┃
               │┗━━━━━━━━━━━━━━┿━━━━━━━━━━┛
               ▼     ▲         │    ▲ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
           ┏━━━┳━━━┓ │         │    │ ┃ balance: 50                   ┃◄─ E1
           ┃ • ┃ • ╂─┘         │    │ ┃ withdraw ──────────────────┐  ┃
           ┗━┿━┻━━━┛           │    └─┨ deposit  ─────────┐        │  ┃
             ▼                 │      ┃ dispatch ┐        │        │  ┃
    параметры: balance         │      ┗━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━┿━━┛
    тело:                      │       ▲         │ ▲      │ ▲      │ ▲
    ((define withdraw ...)     ▼       │         ▼ │      ▼ │      ▼ │
     (define deposit ...)    ┏━━━┳━━━┓ │     ┏━━━┳━┿━┓┏━━━┳━┿━┓┏━━━┳━┿━┓
     (define dispatch ...)   ┃ • ┃ • ╂─┘     ┃ • ┃ • ┃┃ • ┃ • ┃┃ • ┃ • ┃
     dispatch)               ┗━┿━┻━━━┛       ┗━┿━┻━━━┛┗━┿━┻━━━┛┗━┿━┻━━━┛
                               │ ┌─────────────┘        │        │
                               ▼ ▼                      ▼        ▼
                             параметры: m     параметры: amount  параметры: amount
                             тело:            тело: ...          тело: ...
                             (cond
                               ((eq? m 'withdraw) withdraw)
                               ((eq? m 'deposit) deposit)
                               (else (error "Unknown request -- MAKE-ACCOUNT"
                                            m)))

  Окружения, созданные при вычислении ((acc 'deposit) 40):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
     Глобальное ┃ ...                     ┃
    ───────────►┃ acc ─────────┐          ┃
      окружение┌╂ make-account │          ┃
               │┗━━━━━━━━━━━━━━┿━━━━━━━━━━┛
               ▼     ▲         │    ▲ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
           ┏━━━┳━━━┓ │         │    │ ┃ balance: 50                   ┃◄─ E1
           ┃ • ┃ • ╂─┘         │    │ ┃ withdraw ──────────────────┐  ┃
           ┗━┿━┻━━━┛           │    └─┨ deposit  ─────────┐        │  ┃
             ▼             ┌───┼─────►┃ dispatch ┐        │        │  ┃
    параметры: balance     │   │      ┗━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━┿━━┛
    тело:                  │   │       ▲   ▲     │ ▲      │ ▲      │ ▲
    ((define withdraw ...) │   ▼       │   │     ▼ │      ▼ │      ▼ │
     (define deposit ...)  │ ┏━━━┳━━━┓ │   │ ┏━━━┳━┿━┓┏━━━┳━┿━┓┏━━━┳━┿━┓
     (define dispatch ...) │ ┃ • ┃ • ╂─┘   │ ┃ • ┃ • ┃┃ • ┃ • ┃┃ • ┃ • ┃
     dispatch)             │ ┗━┿━┻━━━┛     │ ┗━┿━┻━━━┛┗━┿━┻━━━┛┗━┿━┻━━━┛
                ┌──────────┘   │ ┌─────────┼───┘        │        │
    ┏━━━━━━━━━━━┷━┓            ▼ ▼         │            ▼        ▼
    ┃ m: 'deposit ┃◄─ E2      параметры: m │   параметры: amount  параметры: amount
    ┗━━━━━━━━━━━━━┛           тело: ...    │   тело: ...          тело: ...
                                           │
                                    ┏━━━━━━┷━━━━━━┓
                                    ┃ amount: 40  ┃◄─ E3
                                    ┗━━━━━━━━━━━━━┛

  Окружения, созданные при вычислении ((acc 'withdraw) 60):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
     Глобальное ┃ ...                     ┃
    ───────────►┃ acc ─────────┐          ┃
      окружение┌╂ make-account │          ┃
               │┗━━━━━━━━━━━━━━┿━━━━━━━━━━┛
               ▼     ▲         │    ▲ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
           ┏━━━┳━━━┓ │         │    │ ┃ balance: 90                   ┃◄─ E1
           ┃ • ┃ • ╂─┘         │    │ ┃ withdraw ──────────────────┐  ┃
           ┗━┿━┻━━━┛           │    └─┨ deposit  ─────────┐        │  ┃
             ▼             ┌───┼─────►┃ dispatch ┐        │        │  ┃
    параметры: balance     │   │      ┗━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━┿━━┛
    тело:                  │   │       ▲   ▲     │ ▲      │ ▲      │ ▲
    ((define withdraw ...) │   ▼       │   │     ▼ │      ▼ │      ▼ │
     (define deposit ...)  │ ┏━━━┳━━━┓ │   │ ┏━━━┳━┿━┓┏━━━┳━┿━┓┏━━━┳━┿━┓
     (define dispatch ...) │ ┃ • ┃ • ╂─┘   │ ┃ • ┃ • ┃┃ • ┃ • ┃┃ • ┃ • ┃
     dispatch)             │ ┗━┿━┻━━━┛     │ ┗━┿━┻━━━┛┗━┿━┻━━━┛┗━┿━┻━━━┛
                ┌──────────┘   │ ┌─────────┼───┘        │        │
    ┏━━━━━━━━━━━┷━━┓           ▼ ▼         │            ▼        ▼
    ┃ m: 'withdraw ┃◄─ E2     параметры: m │   параметры: amount  параметры: amount
    ┗━━━━━━━━━━━━━━┛          тело: ...    │   тело: ...          тело: ...
                                           │
                                    ┏━━━━━━┷━━━━━━┓
                                    ┃ amount: 60  ┃◄─ E3
                                    ┗━━━━━━━━━━━━━┛

  Внутреннее состояние acc хранится в окружении E1. Если создать второй счёт, то внутренние состояния
  счёта acc и acc2 не будут смешиваться, т.к. balance каждого из них хранится в разных окружениях.
  Общим будет глобальное окружение, процедуры глобального окружения и тела процедур из соответствующих
  окружений (но не balance и не кадры, которые будут создаваться при вызове той или иной процедуры):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓  ┌───────────┐
                ┃ ...                                          ┃◄─┘ ┏━━━┳━━━┓ │
     Глобальное ┃ make-account ────────────────────────────────╂───►┃ • ┃ • ╂─┘
    ───────────►┃ acc ────────────────┐                        ┃    ┗━┿━┻━━━┛
      окружение ┃ acc2 ─────────────┐ │                        ┃      ▼
                ┗━━━━━━━━━━━━━━━━━━━┿━┿━━━━━━━━━━━━━━━━━━━━━━━━┛     параметры: balance
                      ▲             │ │                ▲             тело: ((define withdraw ...)
         ┏━━━━━━━━━━━━┷━━━━━━━━━━┓  │ │  ┏━━━━━━━━━━━━━┷━━━━━━━━━━┓         (define deposit ...)
    E2 ─►┃ balance: 100          ┃  │ │  ┃ balance: 30            ┃◄─ E1    (define dispatch ...)
         ┃ withdraw ──────────┐  ┃  │ │  ┃ withdraw ───────────┐  ┃         dispatch)
         ┃ deposit  ┐         │  ┃  │ │  ┃ deposit  ───┐       │  ┃
         ┃ dispatch │         │  ┃◄┐│ │┌►┃ dispatch    │       │  ┃
         ┗━━┿━━━━━━━┿━━━━━━━━━┿━━┛ ││ ││ ┗━━┿━━━━━━━━━━┿━━━━━━━┿━━┛
            │  ▲    │    ▲    │ ▲  ││ ││    │     ▲    │    ▲  │ ▲
            ▼  │    ▼    │    ▼ │  ││ ││    ▼     │    ▼    │  ▼ └─┐
      ┏━━━┳━━━┓│┏━━━┳━━━┓│┏━━━┳━┿━┓││ ││ ┏━━━┳━━━┓│┏━━━┳━━━┓│┏━━━┳━┿━┓
      ┃ • ┃ • ╂┘┃ • ┃ • ╂┘┃ • ┃ • ┃││ ││ ┃ • ┃ • ╂┘┃ • ┃ • ╂┘┃ • ┃ • ┃
      ┗━┿━┻━━━┛ ┗━┿━┻━━━┛ ┗━┿━┻━━━┛││ ││ ┗━┿━┻━━━┛ ┗━┿━┻━━━┛ ┗━┿━┻━━━┛
        │         │         │      ││ ││   │         │         │
        │         │     ┌───┘      ││ ││   └──────┐  │  ┌──────┘
        │         │     │       ┌──┘│ │└──────┐   │  │  │
        │         │     │ ┏━━━┳━┿━┓ │ │ ┏━━━┳━┿━┓ │  │  │
        │         │     │ ┃ • ┃ • ┃◄┘ └►┃ • ┃ • ┃ │  │  │
        │         │     │ ┗━┿━┻━━━┛     ┗━┿━┻━━━┛ │  │  │
        │         │     │   │ ┌───────────┘       │  │  │
        │         │     │   ▼ ▼                   │  │  │
        │         │     │ параметры: m            │  │  │
        │         │     │ тело: ...               │  │  │
        ▼         │     │                         │  │  │
       параметры: m ◄───┼─────────────────────────┘  │  │
       тело: ...  │     │                            │  │
                  ▼     │                            │  │
                 параметры: amount ◄─────────────────┘  │
                 тело: ...                              │
                        ▼                               │
                       параметры: amount ◄──────────────┘
                       тело: ...
|#
    #|
  Упражнение 3.11

  В разделе 3.2.3 мы видели, как модель с окружениями описывает поведение процедур, обладающих внутренним
  состоянием. Теперь мы рассмотрели, как работают локальные определения. Типичная процедура с передачей
  сообщений пользуется и тем, и другим. Рассмотрим процедуру моделирования банковского счета из раздела
  3.1.1:

    (define (make-account balance)
      (define (withdraw amount)
        (if (>= balance amount)
            (begin (set! balance (- balance amount))
              balance)
            "Insufficient funds"))
      (define (deposit amount)
        (set! balance (+ balance amount))
        balance)
      (define (dispatch m)
        (cond ((eq? m 'withdraw) withdraw)
              ((eq? m 'deposit) deposit)
              (else (error "Unknown request -- MAKE-ACCOUNT"
                           m))))

      dispatch)

  Покажите, какая структура окружений создается последовательностью действий

    (define acc (make-account 50))

    ((acc 'deposit) 40)
    90

    ((acc 'withdraw) 60)
    30

  Где хранится внутреннее состояние acc? Предположим, что мы определяем еще один счет

    (define acc2 (make-account 100))

  Каким образом удается не смешивать внутренние состояния двух счетов? Какие части структуры окружений
  общие у acc и acc2?
|#

#|
  Процедурные объекты в глобальном кадре окружения для (define acc (make-account 50)):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
     Глобальное ┃ ...                     ┃
    ───────────►┃ acc ─────────┐          ┃
      окружение┌╂ make-account │          ┃
               │┗━━━━━━━━━━━━━━┿━━━━━━━━━━┛
               ▼     ▲         │    ▲ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
           ┏━━━┳━━━┓ │         │    │ ┃ balance: 50                   ┃◄─ E1
           ┃ • ┃ • ╂─┘         │    │ ┃ withdraw ──────────────────┐  ┃
           ┗━┿━┻━━━┛           │    └─┨ deposit  ─────────┐        │  ┃
             ▼                 │      ┃ dispatch ┐        │        │  ┃
    параметры: balance         │      ┗━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━┿━━┛
    тело:                      │       ▲         │ ▲      │ ▲      │ ▲
    ((define withdraw ...)     ▼       │         ▼ │      ▼ │      ▼ │
     (define deposit ...)    ┏━━━┳━━━┓ │     ┏━━━┳━┿━┓┏━━━┳━┿━┓┏━━━┳━┿━┓
     (define dispatch ...)   ┃ • ┃ • ╂─┘     ┃ • ┃ • ┃┃ • ┃ • ┃┃ • ┃ • ┃
     dispatch)               ┗━┿━┻━━━┛       ┗━┿━┻━━━┛┗━┿━┻━━━┛┗━┿━┻━━━┛
                               │ ┌─────────────┘        │        │
                               ▼ ▼                      ▼        ▼
                             параметры: m     параметры: amount  параметры: amount
                             тело:            тело: ...          тело: ...
                             (cond
                               ((eq? m 'withdraw) withdraw)
                               ((eq? m 'deposit) deposit)
                               (else (error "Unknown request -- MAKE-ACCOUNT"
                                            m)))

  Окружения, созданные при вычислении ((acc 'deposit) 40):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
     Глобальное ┃ ...                     ┃
    ───────────►┃ acc ─────────┐          ┃
      окружение┌╂ make-account │          ┃
               │┗━━━━━━━━━━━━━━┿━━━━━━━━━━┛
               ▼     ▲         │    ▲ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
           ┏━━━┳━━━┓ │         │    │ ┃ balance: 50                   ┃◄─ E1
           ┃ • ┃ • ╂─┘         │    │ ┃ withdraw ──────────────────┐  ┃
           ┗━┿━┻━━━┛           │    └─┨ deposit  ─────────┐        │  ┃
             ▼             ┌───┼─────►┃ dispatch ┐        │        │  ┃
    параметры: balance     │   │      ┗━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━┿━━┛
    тело:                  │   │       ▲   ▲     │ ▲      │ ▲      │ ▲
    ((define withdraw ...) │   ▼       │   │     ▼ │      ▼ │      ▼ │
     (define deposit ...)  │ ┏━━━┳━━━┓ │   │ ┏━━━┳━┿━┓┏━━━┳━┿━┓┏━━━┳━┿━┓
     (define dispatch ...) │ ┃ • ┃ • ╂─┘   │ ┃ • ┃ • ┃┃ • ┃ • ┃┃ • ┃ • ┃
     dispatch)             │ ┗━┿━┻━━━┛     │ ┗━┿━┻━━━┛┗━┿━┻━━━┛┗━┿━┻━━━┛
                ┌──────────┘   │ ┌─────────┼───┘        │        │
    ┏━━━━━━━━━━━┷━┓            ▼ ▼         │            ▼        ▼
    ┃ m: 'deposit ┃◄─ E2      параметры: m │   параметры: amount  параметры: amount
    ┗━━━━━━━━━━━━━┛           тело: ...    │   тело: ...          тело: ...
                                           │
                                    ┏━━━━━━┷━━━━━━┓
                                    ┃ amount: 40  ┃◄─ E3
                                    ┗━━━━━━━━━━━━━┛

  Окружения, созданные при вычислении ((acc 'withdraw) 60):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
     Глобальное ┃ ...                     ┃
    ───────────►┃ acc ─────────┐          ┃
      окружение┌╂ make-account │          ┃
               │┗━━━━━━━━━━━━━━┿━━━━━━━━━━┛
               ▼     ▲         │    ▲ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
           ┏━━━┳━━━┓ │         │    │ ┃ balance: 90                   ┃◄─ E1
           ┃ • ┃ • ╂─┘         │    │ ┃ withdraw ──────────────────┐  ┃
           ┗━┿━┻━━━┛           │    └─┨ deposit  ─────────┐        │  ┃
             ▼             ┌───┼─────►┃ dispatch ┐        │        │  ┃
    параметры: balance     │   │      ┗━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━┿━━┛
    тело:                  │   │       ▲   ▲     │ ▲      │ ▲      │ ▲
    ((define withdraw ...) │   ▼       │   │     ▼ │      ▼ │      ▼ │
     (define deposit ...)  │ ┏━━━┳━━━┓ │   │ ┏━━━┳━┿━┓┏━━━┳━┿━┓┏━━━┳━┿━┓
     (define dispatch ...) │ ┃ • ┃ • ╂─┘   │ ┃ • ┃ • ┃┃ • ┃ • ┃┃ • ┃ • ┃
     dispatch)             │ ┗━┿━┻━━━┛     │ ┗━┿━┻━━━┛┗━┿━┻━━━┛┗━┿━┻━━━┛
                ┌──────────┘   │ ┌─────────┼───┘        │        │
    ┏━━━━━━━━━━━┷━━┓           ▼ ▼         │            ▼        ▼
    ┃ m: 'withdraw ┃◄─ E2     параметры: m │   параметры: amount  параметры: amount
    ┗━━━━━━━━━━━━━━┛          тело: ...    │   тело: ...          тело: ...
                                           │
                                    ┏━━━━━━┷━━━━━━┓
                                    ┃ amount: 60  ┃◄─ E3
                                    ┗━━━━━━━━━━━━━┛

  Внутреннее состояние acc хранится в окружении E1. Если создать второй счёт, то внутренние состояния
  счёта acc и acc2 не будут смешиваться, т.к. balance каждого из них хранится в разных окружениях.
  Общим будет глобальное окружение, процедуры глобального окружения и тела процедур из соответствующих
  окружений (но не balance и не кадры, которые будут создаваться при вызове той или иной процедуры):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓  ┌───────────┐
                ┃ ...                                          ┃◄─┘ ┏━━━┳━━━┓ │
     Глобальное ┃ make-account ────────────────────────────────╂───►┃ • ┃ • ╂─┘
    ───────────►┃ acc ────────────────┐                        ┃    ┗━┿━┻━━━┛
      окружение ┃ acc2 ─────────────┐ │                        ┃      ▼
                ┗━━━━━━━━━━━━━━━━━━━┿━┿━━━━━━━━━━━━━━━━━━━━━━━━┛     параметры: balance
                      ▲             │ │                ▲             тело: ((define withdraw ...)
         ┏━━━━━━━━━━━━┷━━━━━━━━━━┓  │ │  ┏━━━━━━━━━━━━━┷━━━━━━━━━━┓         (define deposit ...)
    E2 ─►┃ balance: 100          ┃  │ │  ┃ balance: 30            ┃◄─ E1    (define dispatch ...)
         ┃ withdraw ──────────┐  ┃  │ │  ┃ withdraw ───────────┐  ┃         dispatch)
         ┃ deposit  ┐         │  ┃  │ │  ┃ deposit  ───┐       │  ┃
         ┃ dispatch │         │  ┃◄┐│ │┌►┃ dispatch    │       │  ┃
         ┗━━┿━━━━━━━┿━━━━━━━━━┿━━┛ ││ ││ ┗━━┿━━━━━━━━━━┿━━━━━━━┿━━┛
            │  ▲    │    ▲    │ ▲  ││ ││    │     ▲    │    ▲  │ ▲
            ▼  │    ▼    │    ▼ │  ││ ││    ▼     │    ▼    │  ▼ └─┐
      ┏━━━┳━━━┓│┏━━━┳━━━┓│┏━━━┳━┿━┓││ ││ ┏━━━┳━━━┓│┏━━━┳━━━┓│┏━━━┳━┿━┓
      ┃ • ┃ • ╂┘┃ • ┃ • ╂┘┃ • ┃ • ┃││ ││ ┃ • ┃ • ╂┘┃ • ┃ • ╂┘┃ • ┃ • ┃
      ┗━┿━┻━━━┛ ┗━┿━┻━━━┛ ┗━┿━┻━━━┛││ ││ ┗━┿━┻━━━┛ ┗━┿━┻━━━┛ ┗━┿━┻━━━┛
        │         │         │      ││ ││   │         │         │
        │         │     ┌───┘      ││ ││   └──────┐  │  ┌──────┘
        │         │     │       ┌──┘│ │└──────┐   │  │  │
        │         │     │ ┏━━━┳━┿━┓ │ │ ┏━━━┳━┿━┓ │  │  │
        │         │     │ ┃ • ┃ • ┃◄┘ └►┃ • ┃ • ┃ │  │  │
        │         │     │ ┗━┿━┻━━━┛     ┗━┿━┻━━━┛ │  │  │
        │         │     │   │ ┌───────────┘       │  │  │
        │         │     │   ▼ ▼                   │  │  │
        └─────────│─────│─► параметры: m ◄────────┘  │  │
                  │     │   тело: ...                │  │
                  ▼     │                            │  │
                 параметры: amount ◄─────────────────┘  │
                 тело: ...                              │
                        ▼                               │
                       параметры: amount ◄──────────────┘
                       тело: ...
|#
    #|
  Упражнение 3.11

  В разделе 3.2.3 мы видели, как модель с окружениями описывает поведение процедур, обладающих внутренним
  состоянием. Теперь мы рассмотрели, как работают локальные определения. Типичная процедура с передачей
  сообщений пользуется и тем, и другим. Рассмотрим процедуру моделирования банковского счета из раздела
  3.1.1:

    (define (make-account balance)
      (define (withdraw amount)
        (if (>= balance amount)
            (begin (set! balance (- balance amount))
              balance)
            "Insufficient funds"))
      (define (deposit amount)
        (set! balance (+ balance amount))
        balance)
      (define (dispatch m)
        (cond ((eq? m 'withdraw) withdraw)
              ((eq? m 'deposit) deposit)
              (else (error "Unknown request -- MAKE-ACCOUNT"
                           m))))

      dispatch)

  Покажите, какая структура окружений создается последовательностью действий

    (define acc (make-account 50))

    ((acc 'deposit) 40)
    90

    ((acc 'withdraw) 60)
    30

  Где хранится внутреннее состояние acc? Предположим, что мы определяем еще один счет

    (define acc2 (make-account 100))

  Каким образом удается не смешивать внутренние состояния двух счетов? Какие части структуры окружений
  общие у acc и acc2?
|#

#|
  Процедурные объекты в глобальном кадре окружения для (define acc (make-account 50)):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
     Глобальное ┃ ...                     ┃
    ───────────►┃ acc ─────────┐          ┃
      окружение┌╂ make-account │          ┃
               │┗━━━━━━━━━━━━━━┿━━━━━━━━━━┛
               ▼     ▲         │    ▲ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
           ┏━━━┳━━━┓ │         │    │ ┃ balance: 50                   ┃◄─ E1
           ┃ • ┃ • ╂─┘         │    │ ┃ withdraw ──────────────────┐  ┃
           ┗━┿━┻━━━┛           │    └─┨ deposit  ─────────┐        │  ┃
             ▼                 │      ┃ dispatch ┐        │        │  ┃
    параметры: balance         │      ┗━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━┿━━┛
    тело:                      │       ▲         │ ▲      │ ▲      │ ▲
    ((define withdraw ...)     ▼       │         ▼ │      ▼ │      ▼ │
     (define deposit ...)    ┏━━━┳━━━┓ │     ┏━━━┳━┿━┓┏━━━┳━┿━┓┏━━━┳━┿━┓
     (define dispatch ...)   ┃ • ┃ • ╂─┘     ┃ • ┃ • ┃┃ • ┃ • ┃┃ • ┃ • ┃
     dispatch)               ┗━┿━┻━━━┛       ┗━┿━┻━━━┛┗━┿━┻━━━┛┗━┿━┻━━━┛
                               │ ┌─────────────┘        │        │
                               ▼ ▼                      ▼        ▼
                             параметры: m     параметры: amount  параметры: amount
                             тело:            тело: ...          тело: ...
                             (cond
                               ((eq? m 'withdraw) withdraw)
                               ((eq? m 'deposit) deposit)
                               (else (error "Unknown request -- MAKE-ACCOUNT"
                                            m)))

  Окружения, созданные при вычислении ((acc 'deposit) 40):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
     Глобальное ┃ ...                     ┃
    ───────────►┃ acc ─────────┐          ┃
      окружение┌╂ make-account │          ┃
               │┗━━━━━━━━━━━━━━┿━━━━━━━━━━┛
               ▼     ▲         │    ▲ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
           ┏━━━┳━━━┓ │         │    │ ┃ balance: 50                   ┃◄─ E1
           ┃ • ┃ • ╂─┘         │    │ ┃ withdraw ──────────────────┐  ┃
           ┗━┿━┻━━━┛           │    └─┨ deposit  ─────────┐        │  ┃
             ▼             ┌───┼─────►┃ dispatch ┐        │        │  ┃
    параметры: balance     │   │      ┗━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━┿━━┛
    тело:                  │   │       ▲   ▲     │ ▲      │ ▲      │ ▲
    ((define withdraw ...) │   ▼       │   │     ▼ │      ▼ │      ▼ │
     (define deposit ...)  │ ┏━━━┳━━━┓ │   │ ┏━━━┳━┿━┓┏━━━┳━┿━┓┏━━━┳━┿━┓
     (define dispatch ...) │ ┃ • ┃ • ╂─┘   │ ┃ • ┃ • ┃┃ • ┃ • ┃┃ • ┃ • ┃
     dispatch)             │ ┗━┿━┻━━━┛     │ ┗━┿━┻━━━┛┗━┿━┻━━━┛┗━┿━┻━━━┛
                ┌──────────┘   │ ┌─────────┼───┘        │        │
    ┏━━━━━━━━━━━┷━┓            ▼ ▼         │            ▼        ▼
    ┃ m: 'deposit ┃◄─ E2      параметры: m │   параметры: amount  параметры: amount
    ┗━━━━━━━━━━━━━┛           тело: ...    │   тело: ...          тело: ...
                                           │
                                    ┏━━━━━━┷━━━━━━┓
                                    ┃ amount: 40  ┃◄─ E3
                                    ┗━━━━━━━━━━━━━┛

  Окружения, созданные при вычислении ((acc 'withdraw) 60):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
     Глобальное ┃ ...                     ┃
    ───────────►┃ acc ─────────┐          ┃
      окружение┌╂ make-account │          ┃
               │┗━━━━━━━━━━━━━━┿━━━━━━━━━━┛
               ▼     ▲         │    ▲ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
           ┏━━━┳━━━┓ │         │    │ ┃ balance: 90                   ┃◄─ E1
           ┃ • ┃ • ╂─┘         │    │ ┃ withdraw ──────────────────┐  ┃
           ┗━┿━┻━━━┛           │    └─┨ deposit  ─────────┐        │  ┃
             ▼             ┌───┼─────►┃ dispatch ┐        │        │  ┃
    параметры: balance     │   │      ┗━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━┿━━┛
    тело:                  │   │       ▲   ▲     │ ▲      │ ▲      │ ▲
    ((define withdraw ...) │   ▼       │   │     ▼ │      ▼ │      ▼ │
     (define deposit ...)  │ ┏━━━┳━━━┓ │   │ ┏━━━┳━┿━┓┏━━━┳━┿━┓┏━━━┳━┿━┓
     (define dispatch ...) │ ┃ • ┃ • ╂─┘   │ ┃ • ┃ • ┃┃ • ┃ • ┃┃ • ┃ • ┃
     dispatch)             │ ┗━┿━┻━━━┛     │ ┗━┿━┻━━━┛┗━┿━┻━━━┛┗━┿━┻━━━┛
                ┌──────────┘   │ ┌─────────┼───┘        │        │
    ┏━━━━━━━━━━━┷━━┓           ▼ ▼         │            ▼        ▼
    ┃ m: 'withdraw ┃◄─ E2     параметры: m │   параметры: amount  параметры: amount
    ┗━━━━━━━━━━━━━━┛          тело: ...    │   тело: ...          тело: ...
                                           │
                                    ┏━━━━━━┷━━━━━━┓
                                    ┃ amount: 60  ┃◄─ E3
                                    ┗━━━━━━━━━━━━━┛

  Внутреннее состояние acc хранится в окружении E1. Если создать второй счёт, то внутренние состояния
  счёта acc и acc2 не будут смешиваться, т.к. balance каждого из них хранится в разных окружениях.
  Общим будет глобальное окружение, процедуры глобального окружения и тела процедур из соответствующих
  окружений (но не balance и не кадры, которые будут создаваться при вызове той или иной процедуры):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓  ┌───────────┐
                ┃ ...                                          ┃◄─┘ ┏━━━┳━━━┓ │
     Глобальное ┃ make-account ────────────────────────────────╂───►┃ • ┃ • ╂─┘
    ───────────►┃ acc ────────────────┐                        ┃    ┗━┿━┻━━━┛
      окружение ┃ acc2 ─────────────┐ │                        ┃      ▼
                ┗━━━━━━━━━━━━━━━━━━━┿━┿━━━━━━━━━━━━━━━━━━━━━━━━┛     параметры: balance
                      ▲             │ │                ▲             тело: ((define withdraw ...)
         ┏━━━━━━━━━━━━┷━━━━━━━━━━┓  │ │  ┏━━━━━━━━━━━━━┷━━━━━━━━━━┓         (define deposit ...)
    E2 ─►┃ balance: 100          ┃  │ │  ┃ balance: 30            ┃◄─ E1    (define dispatch ...)
         ┃ withdraw ──────────┐  ┃  │ │  ┃ withdraw ───────────┐  ┃         dispatch)
         ┃ deposit  ┐         │  ┃  │ │  ┃ deposit  ───┐       │  ┃
         ┃ dispatch │         │  ┃◄┐│ │┌►┃ dispatch    │       │  ┃
         ┗━━┿━━━━━━━┿━━━━━━━━━┿━━┛ ││ ││ ┗━━┿━━━━━━━━━━┿━━━━━━━┿━━┛
            │  ▲    │    ▲    │ ▲  ││ ││    │     ▲    │    ▲  │ ▲
            ▼  │    ▼    │    ▼ │  ││ ││    ▼     │    ▼    │  ▼ └─┐
      ┏━━━┳━━━┓│┏━━━┳━━━┓│┏━━━┳━┿━┓││ ││ ┏━━━┳━━━┓│┏━━━┳━━━┓│┏━━━┳━┿━┓
      ┃ • ┃ • ╂┘┃ • ┃ • ╂┘┃ • ┃ • ┃││ ││ ┃ • ┃ • ╂┘┃ • ┃ • ╂┘┃ • ┃ • ┃
      ┗━┿━┻━━━┛ ┗━┿━┻━━━┛ ┗━┿━┻━━━┛││ ││ ┗━┿━┻━━━┛ ┗━┿━┻━━━┛ ┗━┿━┻━━━┛
        │         │         │      ││ ││   │         │         │
        │         │     ┌───┘      ││ ││   └──────┐  │  ┌──────┘
        │         │     │       ┌──┘│ │└──────┐   │  │  │
        │         │     │ ┏━━━┳━┿━┓ │ │ ┏━━━┳━┿━┓ │  │  │
        │         │     │ ┃ • ┃ • ┃◄┘ └►┃ • ┃ • ┃ │  │  │
        │         │     │ ┗━┿━┻━━━┛     ┗━┿━┻━━━┛ │  │  │
        │         │     │   │ ┌───────────┘       │  │  │
        │         │     │   ▼ ▼                   │  │  │
        │         │     │ параметры: m            │  │  │
        │         │     │ тело: ...               │  │  │
        ▼         │     │                         │  │  │
       параметры: m ◄───┼─────────────────────────┘  │  │
       тело: ...  │     │                            │  │
                  ▼     │                            │  │
                 параметры: amount ◄─────────────────┘  │
                 тело: ...                              │
                        ▼                               │
                       параметры: amount ◄──────────────┘
                       тело: ...
|#
    #|
  Упражнение 3.11

  В разделе 3.2.3 мы видели, как модель с окружениями описывает поведение процедур, обладающих внутренним
  состоянием. Теперь мы рассмотрели, как работают локальные определения. Типичная процедура с передачей
  сообщений пользуется и тем, и другим. Рассмотрим процедуру моделирования банковского счета из раздела
  3.1.1:

    (define (make-account balance)
      (define (withdraw amount)
        (if (>= balance amount)
            (begin (set! balance (- balance amount))
              balance)
            "Insufficient funds"))
      (define (deposit amount)
        (set! balance (+ balance amount))
        balance)
      (define (dispatch m)
        (cond ((eq? m 'withdraw) withdraw)
              ((eq? m 'deposit) deposit)
              (else (error "Unknown request -- MAKE-ACCOUNT"
                           m))))

      dispatch)

  Покажите, какая структура окружений создается последовательностью действий

    (define acc (make-account 50))

    ((acc 'deposit) 40)
    90

    ((acc 'withdraw) 60)
    30

  Где хранится внутреннее состояние acc? Предположим, что мы определяем еще один счет

    (define acc2 (make-account 100))

  Каким образом удается не смешивать внутренние состояния двух счетов? Какие части структуры окружений
  общие у acc и acc2?
|#

#|
  Процедурные объекты в глобальном кадре окружения для (define acc (make-account 50)):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
     Глобальное ┃ ...                     ┃
    ───────────►┃ acc ─────────┐          ┃
      окружение┌╂ make-account │          ┃
               │┗━━━━━━━━━━━━━━┿━━━━━━━━━━┛
               ▼     ▲         │    ▲ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
           ┏━━━┳━━━┓ │         │    │ ┃ balance: 50                   ┃◄─ E1
           ┃ • ┃ • ╂─┘         │    │ ┃ withdraw ──────────────────┐  ┃
           ┗━┿━┻━━━┛           │    └─┨ deposit  ─────────┐        │  ┃
             ▼                 │      ┃ dispatch ┐        │        │  ┃
    параметры: balance         │      ┗━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━┿━━┛
    тело:                      │       ▲         │ ▲      │ ▲      │ ▲
    ((define withdraw ...)     ▼       │         ▼ │      ▼ │      ▼ │
     (define deposit ...)    ┏━━━┳━━━┓ │     ┏━━━┳━┿━┓┏━━━┳━┿━┓┏━━━┳━┿━┓
     (define dispatch ...)   ┃ • ┃ • ╂─┘     ┃ • ┃ • ┃┃ • ┃ • ┃┃ • ┃ • ┃
     dispatch)               ┗━┿━┻━━━┛       ┗━┿━┻━━━┛┗━┿━┻━━━┛┗━┿━┻━━━┛
                               │ ┌─────────────┘        │        │
                               ▼ ▼                      ▼        ▼
                             параметры: m     параметры: amount  параметры: amount
                             тело:            тело: ...          тело: ...
                             (cond
                               ((eq? m 'withdraw) withdraw)
                               ((eq? m 'deposit) deposit)
                               (else (error "Unknown request -- MAKE-ACCOUNT"
                                            m)))

  Окружения, созданные при вычислении ((acc 'deposit) 40):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
     Глобальное ┃ ...                     ┃
    ───────────►┃ acc ─────────┐          ┃
      окружение┌╂ make-account │          ┃
               │┗━━━━━━━━━━━━━━┿━━━━━━━━━━┛
               ▼     ▲         │    ▲ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
           ┏━━━┳━━━┓ │         │    │ ┃ balance: 50                   ┃◄─ E1
           ┃ • ┃ • ╂─┘         │    │ ┃ withdraw ──────────────────┐  ┃
           ┗━┿━┻━━━┛           │    └─┨ deposit  ─────────┐        │  ┃
             ▼             ┌───┼─────►┃ dispatch ┐        │        │  ┃
    параметры: balance     │   │      ┗━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━┿━━┛
    тело:                  │   │       ▲   ▲     │ ▲      │ ▲      │ ▲
    ((define withdraw ...) │   ▼       │   │     ▼ │      ▼ │      ▼ │
     (define deposit ...)  │ ┏━━━┳━━━┓ │   │ ┏━━━┳━┿━┓┏━━━┳━┿━┓┏━━━┳━┿━┓
     (define dispatch ...) │ ┃ • ┃ • ╂─┘   │ ┃ • ┃ • ┃┃ • ┃ • ┃┃ • ┃ • ┃
     dispatch)             │ ┗━┿━┻━━━┛     │ ┗━┿━┻━━━┛┗━┿━┻━━━┛┗━┿━┻━━━┛
                ┌──────────┘   │ ┌─────────┼───┘        │        │
    ┏━━━━━━━━━━━┷━┓            ▼ ▼         │            ▼        ▼
    ┃ m: 'deposit ┃◄─ E2      параметры: m │   параметры: amount  параметры: amount
    ┗━━━━━━━━━━━━━┛           тело: ...    │   тело: ...          тело: ...
                                           │
                                    ┏━━━━━━┷━━━━━━┓
                                    ┃ amount: 40  ┃◄─ E3
                                    ┗━━━━━━━━━━━━━┛

  Окружения, созданные при вычислении ((acc 'withdraw) 60):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
     Глобальное ┃ ...                     ┃
    ───────────►┃ acc ─────────┐          ┃
      окружение┌╂ make-account │          ┃
               │┗━━━━━━━━━━━━━━┿━━━━━━━━━━┛
               ▼     ▲         │    ▲ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
           ┏━━━┳━━━┓ │         │    │ ┃ balance: 90                   ┃◄─ E1
           ┃ • ┃ • ╂─┘         │    │ ┃ withdraw ──────────────────┐  ┃
           ┗━┿━┻━━━┛           │    └─┨ deposit  ─────────┐        │  ┃
             ▼             ┌───┼─────►┃ dispatch ┐        │        │  ┃
    параметры: balance     │   │      ┗━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━┿━━┛
    тело:                  │   │       ▲   ▲     │ ▲      │ ▲      │ ▲
    ((define withdraw ...) │   ▼       │   │     ▼ │      ▼ │      ▼ │
     (define deposit ...)  │ ┏━━━┳━━━┓ │   │ ┏━━━┳━┿━┓┏━━━┳━┿━┓┏━━━┳━┿━┓
     (define dispatch ...) │ ┃ • ┃ • ╂─┘   │ ┃ • ┃ • ┃┃ • ┃ • ┃┃ • ┃ • ┃
     dispatch)             │ ┗━┿━┻━━━┛     │ ┗━┿━┻━━━┛┗━┿━┻━━━┛┗━┿━┻━━━┛
                ┌──────────┘   │ ┌─────────┼───┘        │        │
    ┏━━━━━━━━━━━┷━━┓           ▼ ▼         │            ▼        ▼
    ┃ m: 'withdraw ┃◄─ E2     параметры: m │   параметры: amount  параметры: amount
    ┗━━━━━━━━━━━━━━┛          тело: ...    │   тело: ...          тело: ...
                                           │
                                    ┏━━━━━━┷━━━━━━┓
                                    ┃ amount: 60  ┃◄─ E3
                                    ┗━━━━━━━━━━━━━┛

  Внутреннее состояние acc хранится в окружении E1. Если создать второй счёт, то внутренние состояния
  счёта acc и acc2 не будут смешиваться, т.к. balance каждого из них хранится в разных окружениях.
  Общим будет глобальное окружение, процедуры глобального окружения и тела процедур из соответствующих
  окружений (но не balance и не кадры, которые будут создаваться при вызове той или иной процедуры):

                ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓  ┌───────────┐
                ┃ ...                                          ┃◄─┘ ┏━━━┳━━━┓ │
     Глобальное ┃ make-account ────────────────────────────────╂───►┃ • ┃ • ╂─┘
    ───────────►┃ acc ────────────────┐                        ┃    ┗━┿━┻━━━┛
      окружение ┃ acc2 ─────────────┐ │                        ┃      ▼
                ┗━━━━━━━━━━━━━━━━━━━┿━┿━━━━━━━━━━━━━━━━━━━━━━━━┛     параметры: balance
                      ▲             │ │                ▲             тело: ((define withdraw ...)
         ┏━━━━━━━━━━━━┷━━━━━━━━━━┓  │ │  ┏━━━━━━━━━━━━━┷━━━━━━━━━━┓         (define deposit ...)
    E2 ─►┃ balance: 100          ┃  │ │  ┃ balance: 30            ┃◄─ E1    (define dispatch ...)
         ┃ withdraw ──────────┐  ┃  │ │  ┃ withdraw ───────────┐  ┃         dispatch)
         ┃ deposit  ┐         │  ┃  │ │  ┃ deposit  ───┐       │  ┃
         ┃ dispatch │         │  ┃◄┐│ │┌►┃ dispatch    │       │  ┃
         ┗━━┿━━━━━━━┿━━━━━━━━━┿━━┛ ││ ││ ┗━━┿━━━━━━━━━━┿━━━━━━━┿━━┛
            │  ▲    │    ▲    │ ▲  ││ ││    │     ▲    │    ▲  │ ▲
            ▼  │    ▼    │    ▼ │  ││ ││    ▼     │    ▼    │  ▼ └─┐
      ┏━━━┳━━━┓│┏━━━┳━━━┓│┏━━━┳━┿━┓││ ││ ┏━━━┳━━━┓│┏━━━┳━━━┓│┏━━━┳━┿━┓
      ┃ • ┃ • ╂┘┃ • ┃ • ╂┘┃ • ┃ • ┃││ ││ ┃ • ┃ • ╂┘┃ • ┃ • ╂┘┃ • ┃ • ┃
      ┗━┿━┻━━━┛ ┗━┿━┻━━━┛ ┗━┿━┻━━━┛││ ││ ┗━┿━┻━━━┛ ┗━┿━┻━━━┛ ┗━┿━┻━━━┛
        │         │         │      ││ ││   │         │         │
        │         │     ┌───┘      ││ ││   └──────┐  │  ┌──────┘
        │         │     │       ┌──┘│ │└──────┐   │  │  │
        │         │     │ ┏━━━┳━┿━┓ │ │ ┏━━━┳━┿━┓ │  │  │
        │         │     │ ┃ • ┃ • ┃◄┘ └►┃ • ┃ • ┃ │  │  │
        │         │     │ ┗━┿━┻━━━┛     ┗━┿━┻━━━┛ │  │  │
        │         │     │   │ ┌───────────┘       │  │  │
        │         │     │   ▼ ▼                   │  │  │
        └─────────│─────│─► параметры: m ◄────────┘  │  │
                  │     │   тело: ...                │  │
                  ▼     │                            │  │
                 параметры: amount ◄─────────────────┘  │
                 тело: ...                              │
                        ▼                               │
                       параметры: amount ◄──────────────┘
                       тело: ...
|#