Основы функционального программирования

       

Программы для Лисп-интерпретатора.


Цель этой части — помочь избежать некоторых общих ошибок при отладке программ.

(CAR '(A B)) = (CAR (QUOTE(A B))

Пример 5.2.

Функция: CAR

Аргументы: ((A B))

Значение есть A. Заметим, что интерпретатор ожидает список аргументов. Единственным аргументом для CAR является (A B). Добавочная пара скобок возникает, т.к. APPLY подается список аргументов.

Можно написать (LAMBDA(X)(CAR X)) вместо просто CAR. Это корректно, но не является необходимым.

(CONS 'A '(B . C))

Пример 5.3.

Функция: CONS

Аргументы: (A (B . C))

Результат (A . (B . C)) программа печати выведет как (A B . C)

((CAR (QUOTE (A . B))) CDR (QUOTE (C . D)))

Пример 5.4.

Функция: CONS

Аргументы: ((CAR (QUOTE (A . B))) (CDR (QUOTE (C . D))))

Значением такого вычисления будет

((CAR (QUOTE (A . B))) . (CDR (QUOTE (C . D))))

Скорее всего, это совсем не то, чего ожидал новичок. Он рассчитывал вместо (CAR (QUOTE (A . B)) получить A и увидеть (A . D) в качестве итогового значения CONS. Интерпретатор настроен не на список уже готовых значений аргументов, а на список выражений, которые будут вычисляться до вызова функции. Кроме очевидного стирания апострофов

(CONS (CAR (QUOTE (A . B))) (CDR (QUOTE (C . D))) )

ниже приведены еще три правильных способа записи нужной формы. Первый состоит в том, что CAR и CDR части функции задаются с помощью LAMBDA в определении функции. Второй заключается в переносе CONS в аргументы и вычислении их с помощью EVAL при пустом а-списке. Третий — в принудительном выполнении константных действий в представлении аргументов.

((LAMBDA (X Y) (CONS (CAR X) (CDR Y))) '(A . B) '(C . D))

Функция: (LAMBDA (X Y) (CONS (CAR X) (CDR Y)))

Аргументы: ((A . B)(C . D))

(EVAL '(CONS (CAR (QUOTE (A . B))) (CDR (QUOTE (C . D)))) Nil)

Функция: EVAL

Аргументы: ((CONS (CAR (QUOTE (A . B))) (CDR (QUOTE (C . D)))) Nil)

Значением того и другого является (A . D)

((LAMBDA (X Y) (CONS (EVAL X) (EVAL Y))) '(CAR (QUOTE (A . B)))' (CDR (QUOTE (C . D))) )

Функция: (LAMBDA (X Y) (CONS (EVAL X) (EVAL Y)))

Аргументы: ((CAR (QUOTE (A . B))) (CDR (QUOTE (C . D))))

Решения этого примера показывают, что грань между функциями и данными достаточно условна — одни и те же вычисления можно осуществить при разном распределении промежуточных вычислений внутри выражения, передвигая эту грань.


Содержание раздела