Harold Abelson and Gerald Jay Sussman with ... - ftp.linux.kiev.ua.
Harold Abelson and Gerald Jay Sussman with ... - ftp.linux.kiev.ua.
Harold Abelson and Gerald Jay Sussman with ... - ftp.linux.kiev.ua.
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
1.1. Элементы программирования 47<br />
(define (sq<strong>ua</strong>re x)<br />
(exp (double (log x))))<br />
(define (double x) (+ x x))<br />
Таким образом, определение процедуры должно быть способно скрывать детали.<br />
Может оказаться, что пользователь процедуры не сам ее написал, а получил<br />
от другого программиста как черный ящик. От пользователя не должно требоваться<br />
знания, как работает процедура, чтобы ее использовать.<br />
Локальные имена<br />
Одна из деталей реализации, которая не должна заботить пользователя процедуры<br />
— это то, какие человек, писавший процедуру, выбрал имена для формальных<br />
параметров процедуры. Таким образом, следующие две процедуры должны<br />
быть неотличимы:<br />
(define (sq<strong>ua</strong>re x) (* x x))<br />
(define (sq<strong>ua</strong>re y) (* y y))<br />
Этот принцип — что значение процедуры не должно зависеть от имен параметров,<br />
которые выбрал ее автор, — может сначала показаться очевидным, однако он<br />
имеет глубокие следствия. Простейшее из этих следствий состоит в том, что имена<br />
параметров должны быть локальными в теле процедуры. Например, в программе<br />
вычисления квадратного корня при определении good-enough? мы использовали<br />
sq<strong>ua</strong>re:<br />
(define (good-enough? guess x)<br />
(< (abs (- (sq<strong>ua</strong>re guess) x)) 0.001))<br />
Намерение автора good-enough? состоит в том, чтобы определить, достаточно<br />
ли близко квадрат первого аргумента лежит ко второму. Мы видим, что автор<br />
good-enough? обращается к первому аргументу с помощью имени guess, а ко<br />
второму с помощью имени x. Аргументом sq<strong>ua</strong>re является guess. Поскольку автор<br />
sq<strong>ua</strong>re использовал имя x (как мы видели выше), чтобы обратиться к этому<br />
аргументу, мы видим, что x в good-enough? должно отличаться от x в sq<strong>ua</strong>re.<br />
Запуск процедуры sq<strong>ua</strong>re не должен отразится на значении x, которое использует<br />
good-enough?, поскольку это значение x понадобится good-enough?, когда<br />
sq<strong>ua</strong>re будет вычислена.<br />
Если бы параметры не были локальны по отношению к телам своих процедур,<br />
то параметр x в sq<strong>ua</strong>re смешался бы с параметром x из good-enough?, и поведение