24.03.2015 Views

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.

SHOW MORE
SHOW LESS

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?, и поведение

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!