ФУНКЦИИ
Функции в Лиспе аналогично математическим функциям ставят в соответствие элементам из одного множества - определения (аргументов) - единственный элемент из множества значений. В программах следует различать определение функций и вызов (применение) функции.
В языке Лисп принята единообразная префиксная форма записи, при которой как имя функции или действия, так и аргументы записываются внутри скобок:
(f x)
(g x y) (сумма_квадратов 2 3).
Аналогично записываются и арифметические действия:
(+ х у)
(*x(+yz))
(+ (^ х х) (+ у у)).
Определение функций и их вычисление в Лиспе основано на лямбда-исчислении Черча. В 1-исчислении Черча функция записывается в виде
1(х1,х2,... ,xn) .fn
В Лиспе 1-выражение имеет вид (LAMBDA (xl, x2,..., xn).fn).
Символ LAMBDA означает, что мы имеем дело с определением функции. Символы xi являются формальными параметрами, они образуют список, называемый лямбда-списком; fn - это тело функции, которая может иметь произвольную форму, допускаемую интерпретатором Лиспа. Телом функции может быть, например, константа или композиция из вызовов функций. Функцию, вычисляющую сумму квадратов двух чисел, можно, например, определить так:
(lambda(xy)(+(*xx)(*yy))).
Лямбда-выражение - это безымянная функция, которая может быть использована для связывания формальных и фактических параметров на время вычислений. Вызов такой функции происходит по форме
(лямбда-выражение а1 а2 ... an)
Здесь ai - фактические параметры, с которыми происходит вычисление.
Например
((lambda (х у) (+ (* х х) (* у у))) 3 4).
Результат: 25.
Определить новую функцию и дать ей имя для последующих вызовов можно с помощью функции DEFUN (define function):
(DEFUN имя лямбда-список тело).
DEFUN соединяет символ с лямбда-выражением, и символ начинает представлять (именовать) определенные этим лямбда-выражением вычисления. Значением этой формы является имя новой функции:
(defun sumsquare (х у) (+ (* х х) (* у у))) .
Результат: sumsquare.
Вызов (применение) этой функции:
(sumsquare 34)
Результат: 25.
Определение функции задается списком, поэтому его можно модифицировать в ходе выполнения программы. Кроме того, некоторый символ может быть и именем функции и переменной.
В Лиспе передача параметров происходит по значению. Формальные параметры функций являются статическими и локальными, т.е. действительны только внутри той формы, в которой они определены.
Основу для построения различных функций образует набор небольшого числа примитивных встроенных функций. Базовыми функциями обработки S-выражений являются функции
CAR, CDR, CONS, ATOM, EQ, EQL, =
и другие, смысл которых отражен в табл. 3.7.
Таблица 3.7
Базовые функции обработки 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, является побочным эффектом , этих функций, помимо того, данные функции возвращают присваиваемые значения.