Code Review
Compare your solutions
#|
Упражнение 3.10
В процедуре make-withdraw локальная переменная balance создается в виде параметра make-withdraw. Можно
было бы создать локальную переменную и явно, используя let, а именно:
(define (make-withdraw initial-amount)
(let ((balance initial-amount))
(lambda (amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))))
Напомним, что в разделе 1.3.2 говорится, что let всего лишь синтаксический сахар для вызова процедуры:
(let ((<var> <exp>)) <body>)
интерпретируется как альтернативный синтаксис для
((lambda (<var>) <body>) <exp>)
С помощью модели с окружениями проанализируйте альтернативную версию make-withdraw. Нарисуйте картинки,
подобные приведенным в этом разделе, для выражений
(define W1 (make-withdraw 100))
(W1 50)
(define W2 (make-withdraw 100))
Покажите, что две версии make-withdraw создают объекты с одинаковым поведением. Как различаются\
структуры окружений в двух версиях?
|#
#|
Процедурные объекты в глобальном кадре окружения для (define W1 (make-withdraw 100)):
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
Глобальное ┃ make-withdraw ────────────────────┐ ┃
───────────►┃ ... │ ┃◄────┐
окружение ┃ W1 │ ┃ │
┗━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━┛ │
│ ▲ ▼ │
│ ┏━━━━━━━━━━┷━━━━━━━━━━┓ ┏━━━┳━━━┓ │
│ ┃ initial-amount: 100 ┃◄─ E1 ┃ • ┃ • ╂─┘
│ ┗━━━━━━━━━━━━━━━━━━━━━┛ ┗━┿━┻━━━┛
│ ▲ ▼
│ ┏━━━━━━━━━━┷━━━━━━━━━━┓ параметры: initial-amount
│ ┃ balance: 100 ┃◄─ E2 тело: (let ((balance initial-amount))
│ ┗━━━━━━━━━━━━━━━━━━━━━┛ (lambda (amount)
▼ ▲ (if (>= balance amount)
┏━━━┳━━━┓ │ (begin (set! balance (- balance amount))
┃ • ┃ • ╂─┘ balance)
┗━┿━┻━━━┛ "Insufficient funds"))))
▼
параметры: amount
тело: (if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))))
Окружения, созданные при вычислении (W1 50):
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
Глобальное ┃ make-withdraw ────────────────────┐ ┃
───────────►┃ ... │ ┃◄────┐
окружение ┃ W1 │ ┃ │
┗━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━┛ │
│ ▲ ▼ │
│ ┏━━━━━━━━━━┷━━━━━━━━━━┓ ┏━━━┳━━━┓ │
│ ┃ initial-amount: 100 ┃◄─ E1 ┃ • ┃ • ╂─┘
│ ┗━━━━━━━━━━━━━━━━━━━━━┛ ┗━┿━┻━━━┛
│ ▲ ▼
│ ┏━━━━━━━━━━┷━━━━━━━━━━┓ параметры: initial-amount
│ ┃ balance: 100 ┃◄─ E2 тело: (let ((balance initial-amount))
│ ┗━━━━━━━━━━━━━━━━━━━━━┛ (lambda (amount)
▼ ▲ ▲ (if (>= balance amount)
┏━━━┳━━━┓ │ ┏━━━━┷━━━━━━━━━━━━━━━━┓ (begin (set! balance (- balance amount))
┃ • ┃ • ╂─┘ ┃ amount: 50 ┃◄─ E3 balance)
┗━┿━┻━━━┛ ┗━━━━━━━━━━━━━━━━━━━━━┛ "Insufficient funds"))))
▼
параметры: amount
тело: (if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))))
Процедурные объекты в глобальном кадре окружения для (define W2 (make-withdraw 100)):
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┌──────────┐
Глобальное ┃ ... ┃◄─┘ ┏━━━┳━━━┓│
───────────►┃ make-withdraw ────────────────────────╂───►┃ • ┃ • ╂┘
окружение ┃ W2 ───────────────────────────────────╂───┐┗━┿━┻━━━┛
┌───╂ W1 ┃ │ │
│ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ │ ▼
│ ▲ ▲ │ параметры: initial-amount
│┏━━━━━━━━━━┷━━━━━━━━━━┓ ┏━━━━━━━━━━┷━━━━━━━━━━┓│ тело: (let ((balance initial-amount))
E1 ─►┃ initial-amount: 100 ┃ ┃ initial-amount: 100 ┃◄─ E3 (lambda (amount)
│┗━━━━━━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━━━┛│ (if (>= balance amount)
│ ▲ ▲ │ (begin (set! balance (- balance amount))
│┏━━━━━━━━━━┷━━━━━━━━━━┓ ┏━━━━━━━━━━┷━━━━━━━━━━┓│ balance)
E2 ─►┃ balance: 50 ┃ ┃ balance: 100 ┃◄─ E4 "Insufficient funds"))))
│┗━━━━━━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━━━┛│
▼ ▲ ▲ ▼
┏━━━┳━━━┓ │ │ ┏━━━┳━━━┓
┃ • ┃ • ╂─┘ │ ┃ • ┃ • ╂┐
┗━┿━┻━━━┛ │ ┗━┿━┻━━━┛│
│ ┌───┐ └─────┼──────┘
▼ ▼ └───────────────────────────────────────┘
параметры: amount
тело: (if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))))
|#