1.1. Элементы программирования
45
жет оказаться, что пользователь процедуры не сам ее написал, а получил от другого
программиста как черный ящик. От пользователя не должно требоваться знания, как
работает процедура, чтобы ее использовать.
Локальные имена
Одна из деталей реализации, которая не должна заботи ть пользователя процедуры —
это то, какие человек, писавший процедуру, выбрал имена для формальных параметров
процедуры. Таким образом, следующие две процедуры должны быть неотличимы:
(define (square x) (* x x))
(define (square y) (* y y))
Этот принцип — что значение процедуры не должно зависеть от имен параметров, кото-
рые выбрал ее автор, — может сначала показаться очевидным, однако он имеет глубокие
следс твия. Простейшее из э тих следствий состоит в том, что имена параметров должны
быть локальными в теле процедуры. Например, в программе вычисления квадратного
корня при определени и good-enough? мы использовали square:
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
Намерение автора good-enough? состоит в том, чтобы определить, достаточно ли близ-
ко квадрат первого аргумента лежит ко второму. Мы видим, что автор good-enough?
обращается к первому аргументу с помощью имени guess, а ко второму с помощью
имени x. Аргументом square является guess. Поскольку автор square использовал
имя x (как мы видели выше ), чтобы обратиться к этому аргументу, мы видим, что
x в good-enough? должно отличаться от x в square. Запуск процедуры square не
должен отразится на значении x, которое использует good-enough?, поскольку это
значение x понадобится good-enough?, когда square будет вычислена.
Если бы параметры не были локал ьны по отношению к телам своих процедур, то
параметр x в square смешался бы с параметром x из good-enough?, и поведение
good-enough? зависело бы от того, какую версию square мы использовали. Таким
образом, процедура square не была бы черным ящиком, как мы того хотим.
У формального параметра особая роль в определении процедуры: не имеет значе-
ния, какое у этого параметра имя. Такое имя называется связанной переменной (bound
variable), и мы будем говорить, что определение процедуры связывает (binds) свои фор-
мальные параметры. Значение процедуры не изменяется, если во всем ее определении
параметры последовательным образом переименованы
26
. Если переменная не связана,
мы говорим, ч то она свободна (free). Множество выражений, для которых связывание
определяет имя, называется областью действия (scope) этого имени. В определении
процедуры связанные переменные, объя вленные как формальные параме тры процедуры,
имеют своей областью действия тело процедуры.
В приведенном выше определении good-enough?, guess и x — связанные пере-
менные, а <, -, abs и square — свободные. Значение good-enough? должно быть
26
Понятие последовательного переименования на самом деле достаточно тонкое и трудное для определения.
Знаменитым логикам случалось делать здесь ужасные ошибки.