Базовые функции обработки S-выражений
Функция
| Вызов
| Действие
| Пример использования
| CAR
| (CAR список)
| Возвращает головною часть
| (CAR(1 234))
|
|
| списка - его 1-й элемент
| Результат:1
| CDR
| (CDR список)
| Возвращает хвостовую часть
| (CDR(! 234))
|
|
| списка- все. кроме 1-го элемента
| Результат:(2 3 4)
| CONS
| (CONS S-выра-
| Строит список из переданных в
| (CONS I (2 3 4))
|
| жение список)
| качестве аргументов головы и хвоста
| Результат: (1234)
| ATOM
| (ATOMS-выра-
| Предикат; проверяет, является ли
| (ATOM A) : t
|
| жение)
| аргумент атомом, и возвращает либо t
| (ATOM (1 2 3)): Nil
|
|
| (истина), либо Nil или ("(ложь)
|
| EQ
| (EQ символ
| Предикат: проверяет тождественность
| (EQ A A): t
|
| символ)
| символов-аргументов, неприменим
| (EQ X (CAR (X Y Z))): t
|
|
| для чисел
|
| EQL
| (EQL число
| Предикат, проверяет тождественность
| (EQL 3.0 3.0): t
|
| число)
| чисел одного типа
|
| =
| (= число
| Предикат, проверяет тождественность
|
|
| число)
| чисел различных типов
| (=30.3el):t
| EQUAL
| (EQUAL число
| Аналогична EQL,
| (EQUAL(xyz)(xyz)):t
|
| или список
| но, кроме того, проверяет идентичность
|
|
| число или список)
| Списков
|
| EQUALP
| (EQUALP
| Проверка наиболее общего равенства
|
|
| объект объект)
|
|
| NULL
| (NULL список)
| Проверка, является ли аргумент
|
|
|
| пустым списком
|
| NOT
| (NOT логическая
| Логическое отрицание
|
|
| величина)
|
|
| NTH
| (NTH n список)
| Выделение n-го элемента списка
| (NTH 2 (1 2 3)): 3
|
|
|
| (индексы начинаются с 0)
| FIRST
|
| Предикаты, выделяющие
|
| SECOND
|
| Соответствующие элементы списка
|
| LAST
|
|
|
| LIST
| (LIST apr
| Строит из аргументов список
| (LIST a b (с)): (a b c)
|
| арг2 ...)
|
|
|
Отметим, что в программах на Лиспе надо тщательно отличать значения от их обозначений.
В Лиспе константы обозначают самих себя. Выражения типа (* 2 2) сразу вычисляются. Чтобы избежать нежелательного вычисления выражения используется функция QUOTE или знак апострофа (') перед выражением:
(* 2 2) : 4
' (* 2 2) :' (* 2 2) – список
Произвольный символ можно использовать как переменную, и он может обозначать произвольное выражение. При первом использовании символу должно быть присвоено или с ним связано некоторое значение с помощью функции SET, например,
(SET 'операции'(+ - */))
Знак ' используется для подавления вычисления аргументов функции SET. Функция SETQ не вычисляет значения 1-го аргумента (а 2-го вычисляет).
На значение символа можно сослаться, указав его без апострофа (').
Для занесения значений в ячейку памяти, связанной с символом, можно пользоваться обобщенной функцией присваивания SETF, размещающей значения в соответствующей ячейке памяти:
(SETF ячейка_памяти значение).
Переменная «ячейка_памяти» без апострофа указывает на ячейку памяти. Присвоение, выполняемое функциям» SET, SETQ и SETF, является побочным эффектом , этих функций, помимо того, данные функции возвращают присваиваемые значения.
ФОРМЫ. УПРАВЛЯЮЩИЕ КОНСТРУКЦИИ В ЛИСП-ПРОГРАММЕ
Программа состоит не только из функций, но и из форм. Простейшими формами являются константы, переменные, лямбда-вызовы, вызовы функций.
Остановимся более подробно на специальных формах, предназначенных для управления обработкой программы и контекстом. У каждой формы определенный синтаксис и семантика, основанные на едином способе записи и интерпретации.
Управляющие предложения Лиспа внешне выглядят как вызовы функций - в виде скобочных выражений, первый элемент которых действует как имя управляющей структуры, а остальные элементы - как аргументы. Наиболее важные формы можно разделить на следующие группы:
Работа с контекстом
• QUOTE или блокировка вычисления,
• вызов функции и лямбда-вызов,
• предложения LET и LET*;
Последовательное исполнение
• предложения PROG1, PROG2 и PROGN;
Разветвление исполнения
• условные предложения COND, IF, WHEN, UNLESS,
• выбирающее предложение CASE;
Итерации
• циклические предложения DO, DO*, LOOP, DOTIMES, DOUNTIL;
Передачи управления
• предложения PROG, GO и RETURN;
Динамическое управление вычислением
• THROW, CATCH, а также BLOCK.
Эти управляющие формы (кроме QUOTE и лямбда-вызова, а также вызовов функций), в основном, используются в теле лямбда-выражений, определяющих функции.
Предложение LET используется для создания связи переменных внутри формы:
(LET ((пep1 знач1) (пер2 знач2)...) форма1 форма2 ...).
При вычислении этого выражения статические переменные пep1, пер2, ... связываются (одновременно) с соответствующими значениями знач1, знач2, ..., а затем вычисляются значения форм форма1, форма2, ... Значение последней формы возвращается как общий результат. Форма LET* отличается от LET лишь тем, что связывание переменных и вычисление форм происходит не одновременно, а последовательно, вначале 1-е, потом 2-е и т.д.
Например:
(let*((x2)(y(*3x)))
(list x у)
Результат: (2 6).
Предложения PROG1, PROG2 и PROGN позволяют организовывать последовательные вычисления из нескольких вычисляемых форм:
(PROG1 форма1 форма2 ... формаn)
(PROG2 форма1 форма2 .. формаn)
(PROGN форма1 форма2 . формаn).
Различие этих форм лишь в возвращаемых ими в качестве общего значения результатах. Форма PROG1 возвращает значение формы1, PROG2-формы2, PROGN -последней формы n.
Например:
(progn (setq x 2) (setq у (* 3 х)))
Результат: 6.
Предложение COND является основным средством разветвления обработки. Структура условного предложения такова:
(COND (р1 а1) (р2 а2)... (pn an)).
pi - это предикаты (выражения-условия, которые могут быть либо истинными (Т), либо ложными (NIL)). Их значения вычисляются слева направо, пока не будет получено значение «истина» (Т), затем вычисляется и возвращается в качестве результата результирующее выражение ai. соответствующее 1-му истинному предикату pi. Если истинного предиката нет. то значение COND - NIL. Форма ai для соответствующего предиката может отсутствовать (тогда возвращается значение этого предиката в случае его истинности), или, наоборот, может быть задана последовательность форм для предиката pi - тогда эти формы вычисляются последовательно и возвращается значение последней.
В следующем примере с помощью предложения COND определена функция, устанавливающая тип выражения:
(defun тип (1)
(cond ((null 1) 'пусто)
((atom 1) 'атом)
(t 'список)))
Результат: ТИП.
Примеры применения этой функции:
(тип ' (a b с))
Результат: СПИСОК.
(тип (atom ' (а т ом)))
Результат: ПУСТО.
Для организации ветвления можно использовать и формулы IF, WHEN, UNLESS:
(IF условие то-форма иначе-форма),
что эквивалентно
(COND (условие то-форма) (Т иначе форма));
(WHEN условие форма1 форма2 ...),
что эквивалентно
(UNLESS (NOT условие) форма! форма2 ...)
или
(COND (условие форма1 форма2 ...)).
Можно применять и выбирающее предложение CASE:
(CASE ключ (список ключей1 форма11 форма12 ...)
(список ключей2 форма21 форма22 . . .)
В этой форме сначала вычисляется значение ключевой формы «ключ», затем происходит сравнение с элементами списков ключей и, если найдено значение ключевой формы, вычисляется последовательность соответствующих форм, значение последней из которых возвращается как значение всего выражения CASE.
Предложения PROG, GO и RETURN аналогичны конструкциям неструктурных языков программирования (типа FORTRAN, Бейсик); пользоваться ими не рекомендуется.
|