Лямбда - выражения и пользовательские функции — КиберПедия 

Историки об Елизавете Петровне: Елизавета попала между двумя встречными культурными течениями, воспитывалась среди новых европейских веяний и преданий...

Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...

Лямбда - выражения и пользовательские функции

2018-01-03 343
Лямбда - выражения и пользовательские функции 0.00 из 5.00 0 оценок
Заказать работу

 

Введём понятие формы. Формой в языке Lisp называется любая управляющая конструкция (т.е. конструкция, которая может быть вычислена). Примерами форм может быть (+ 1 2) или (LIST 'A '(B C) 'D). Надо отметить, что оператор, содержащий в себе формы, сам может являться формой. Атомы также являются формами.

Форма является важным понятием, с помощью которого мы в дальнейшем будем описывать вызовы функций. Если в предыдущей главе все функции работали с атомами или списками, то здесь будут рассматриваться функции, принимающие своими параметрами управляющие конструкции языка Lisp.

Основой любых вычислений в языке Lisp являются лямбда-выражения, которые, в свою очередь, берут за основу теорию лямбда-исчисления Черча (описанную в разделе 2).

В Lisp общее представление лямбда-выражения имеет вид (LAMBDA (X1 X2 … XN) Fn), где символ LAMBDA указывает на определение функции.

 

lambda (LAMBDA ((формальные_параметры) тело_функции)   Создаёт функцию. Список формальных параметров (или так называемый лямбда-список) представляет собой перечисление используемых в теле функции имён переменных. Тело функции может являться произвольной формой.

 

Для того чтобы понять, зачем это нужно, необходимо обратить внимание на форму записи вызовов функций (или лямбда-вызовов) в языке Lisp. Первый элемент списка всегда считается именем функции. Таким образом, можно в качестве некоторого первого элемента списка поставить лямбда-функцию и вычислить её от остальных элементов. С другой стороны, лямбда-вызов может быть также и фактическим параметром некоторой другой функции. Надо отметить, что если лямбда-выражение не используется одним из перечисленных способов, это приводит к ошибке.

В качестве примера приведём вычисления квадрата числа:

>(LAMBDA (X) (* X X)) #<Interpreted Function (unnamed) @ #x204d51ea> >((LAMBDA (X) (* X X)) 2)

Как мы видим, использование ламбда-выражения без вызова привело к бессмысленному результату, однако правильно сформированный лямбда-вызов дал корректный результат.

В некотором приближении лямбда-выражение может считаться функцией без имени. Однако обычно гораздо удобнее формировать описание функции один раз, давать ему имя и впоследствии при вызове обращаться к функции по имени, нежели каждый раз подставлять лямбда-выражение, т.е. полное описание последовательности действий. Некоторые версии Lisp позволяют связывать лямбда-выражения с символами, и впоследствии использовать эти символы в качестве имён, однако данный метод не является общепринятым. Наиболее общим определением имени функции является использование DEFUN:

 

defun (DEFUN имя_функции лямбда-смисок тело_функции) Определяет именованную функцию. Лямбда-список - список параметров, тело - произвольная форма. Впоследствии при обращении к имени функции на его место подставляется лямбда-выражение, составленное из лямбда-списка и тела функции.

 

Возвращаясь к вычислению квадрата числа, мы можем привести аналогичный код, но уже с использованием DEFUN:

>(DEFUN SQUARE (X) (* X X)) SQUARE >(SQUARE 2)

В дальнейшем каждое обращение к SQUARE (до тех пор, пока символ не будет переопределён) будет вычислять квадрат аргумента.

Можно проверить, связан ли символ с функцией. Для этой цели используется функция FBOUNDP:

 

fboundp (FBOUNDP символ) Определяет, связано ли с символом определение функции и возвращает истину если связано и ложь в противном случае.

 

>(FBOUNDP 'SQUARE) T >(FBOUNDP 'SQUARE1) NIL

Данный пример был выполнен в Сlisp. В случае Allegro Common Lisp результат будет другой:

>(FBOUNDP 'SQUARE) #<Interpreted Function SQUARE>

Тем не менее, будучи использован в аргументах других функций, этот вывод на экран соответствует возвращаемому значению T.

Ещё одна любопытная возможность связана со способностью Lisp показывать, каким именно образом функция была определена.

 

Symbol-function (symbol-function символ) Возвращает текстовое определение функции.

 

>(SYMBOL-FUNCTION 'SQUARE) #<CLOSURE SQUARE (X) (DECLARE (SYSTEM::IN-DEFUN SQUARE)) (BLOCK SQUARE (* X X))>

 

Данный пример также выполнен в Clisp.

Для списка аргументов функций допустимо также указывать дополнительные свойства, которые начинаются со знака & и записываются перед объявляемым аргументом функции (использование таких слов – отличительная особенность диалекта COMMON LISP). Это свойства &OPTIONAL, &REST, &KEY и &AUX. Все параметры, объявленные до первого &KEY являются обязательными. Далее, значения параметров, объявленных через &OPTION можно не указывать, и они будут переданы в тело функции как NIL или значением по умолчанию (если оно указано).

>(defun sample (x &optional (y 5)) (* x y)) SAMPLE > (sample 1) >(sample 1 2) >(defun sample2 (&optional y) y) SAMPLE2 >(sample2 1) >(sample2) NIL

Все параметры, которые указываются после слова &REST, передаются в тело программы через список несвязанных параметров (для организации функций с переменным числом параметров).

>(defun sample3 (&rest params) params) SAMPLE3 >(sample3) NIL >(sample3 'A) (A) >(sample3 'A 'B 'C) (A B C)

Отметим, что наряду с (CONS x NIL) подобная функция также может использоваться для задачи помещения атома в скобки.

Параметры, объявленные со свойством &KEY являются необязательными и могут быть переданы в функцию только в виде пары:ИМЯ ЗНАЧЕНИЕ, зато в любом порядке:

>(defun sample4 (&key x y) (list x y)) SAMPLE4 >(sample4) (NIL NIL) >(sample4:x 1) (1 NIL) >(sample4:y 1) (NIL 1)

 

>(sample4:x 1:y 2) (1 2)

Наконец, параметры, объявленные как вспомогательные, являются скорее локальными переменными, нежели аргументами функции и не требуют передачи при вызове.


Поделиться с друзьями:

Таксономические единицы (категории) растений: Каждая система классификации состоит из определённых соподчиненных друг другу...

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...

История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...

Типы оградительных сооружений в морском порту: По расположению оградительных сооружений в плане различают волноломы, обе оконечности...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.009 с.