Введение в программирование на Лиспе

         

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


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

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

Пример 8.2.

(html, txt)

Функция: CAR

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

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

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

(CONS 'A '(B . C))

Пример 8.3.

(html, txt)

Функция: CONS

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

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

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

Пример 8.4.

(html, txt)

Функция: 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))))

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

Таблица 8.1. Clisp: Функции для манипулирования именами и категориями объектов.

(Defconstant Атом Форма )Глобальная константа
(Defparameter Атом Форма )Глобальная переменная
(Defun Название Параметры Форма )Определение функции
(Flet ((Название Параметры Форма) … (Спецификации … Формы …))Вводит локальные нерекурсивные функции
(Labels ( (Название Параметры Форма) … (Спецификации … Формы …) )Вводит локальные рекурсивные функции


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

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

Пример 8.2.

Функция: CAR

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

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

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

(CONS 'A '(B . C))

Пример 8.3.

Функция: CONS

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

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

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

Пример 8.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))))

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

Таблица 8.1. Clisp: Функции для манипулирования именами и категориями объектов.

(Defconstant Атом Форма )Глобальная константа
(Defparameter Атом Форма )Глобальная переменная
(Defun Название Параметры Форма )Определение функции
(Flet ((Название Параметры Форма) … (Спецификации … Формы …))Вводит локальные нерекурсивные функции
(Labels ( (Название Параметры Форма) … (Спецификации … Формы …) )Вводит локальные рекурсивные функции



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