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. Элементы программирования 29<br />
– Вычислить все подвыражения комбинации.<br />
– Применить процедуру, которая является значением самого левого подвыражения<br />
(оператора) к аргументам — значениям остальных подвыражений<br />
(операндов).<br />
Даже в этом простом правиле видны несколько важных свойств процессов в целом.<br />
Прежде всего, заметим, что на первом шаге для того, чтобы провести процесс<br />
вычисления для комбинации, нужно сначала проделать процесс вычисления для<br />
каждого элемента комбинации. Таким образом, правило вычисления рекурсивно<br />
(recursive) по своей природе; это означает, что в качестве одного из своих шагов<br />
оно включает применение того же самого правила 10 .<br />
Заметьте, какую краткость понятие рекурсии придает описанию того, что в<br />
случае комбинации с глубоким вложением выглядело бы как достаточно сложный<br />
процесс. Например, чтобы вычислить<br />
(* (+ 2 (* 4 6))<br />
(+ 3 5 7))<br />
требуется применить правило вычисления к четырем различным комбинациям.<br />
Картину этого процесса можно получить, нарисовав комбинацию в виде дерева,<br />
как показано на рис. 1.1. Каждая комбинация представляется в видевершины, а<br />
ее оператор и операнды — в виде ветвей, исходящих из этой вершины. Концевые<br />
вершины (то есть те, из которых не исходит ни одной ветви) представляют<br />
операторы или числа. Рассматривая вычисление как дерево, мы можем представить<br />
себе, что значения операндов распространяются от концевых вершин вверх<br />
и затем комбинируются на все более высоких уровнях. Впоследствии мы увидим,<br />
что рекурсия — это вообще очень мощный метод обработки иерархических, древовидных<br />
объектов. На самом деле форма правила вычисления «распространить<br />
значения наверх» является примером общего типа процессов, известного как накопление<br />
по дереву (tree accumulation).<br />
Далее, заметим, что многократное применение первого шага приводит нас к<br />
такой точке, где нам нужно вычислять уже не комбинации, а элементарные выражения,<br />
а именно числовые константы, встроенные операторы или другие имена.<br />
С этими случаями мы справляемся, положив, что:<br />
• значением числовых констант являются те числа, которые они называют;<br />
10 Может показаться странным, что правило вычисления предписывает нам в качестве части<br />
первого шага вычислить самый левый элемент комбинации, — ведь до сих пор это мог быть<br />
только оператор вроде + или *, представляющий встроенную процедуру, например, сложение<br />
или умножение. Позже мы увидим, что полезно иметь возможность работать и с комбинациями,<br />
чьи операторы сами по себе являются составными выражениями.