- •Содержание
- •1. Введение в функции
- •1.1. Чистые функции
- •1.2. Функциональность
- •2. Введение в функциональное программирование
- •2.1. О языке Лисп
- •2.2. Примеры программ
- •2.3. Символьная обработка
- •2.4. Особенности Лиспа
- •3. Основы языка лисп
- •3.1. Символы и списки
- •3. 2. Понятие функции
- •3.3. Базовые функции
- •3.4. Имя и значение символа
- •4. Определение функций
- •5. Математические основы: -исчисление
- •5. 1. Введение в синтаксис
- •Определение -термов
- •5.2. Вычисление -выражений
- •5.3. Порядок редукций и нормальные формы
- •5.4. Рекурсивные выражения
- •5.5. Чистое -исчисление
- •5.6. Ламбда-абстракции в Лиспе
- •6. Внутреннее представление списков
- •7. Рекурсия
- •7.1. Простая рекурсия
- •7.2. Другие формы рекурсии
- •8. Функции более высокого порядка
- •8.1. Функционалы
- •8.2. Способы композиции функций
- •8.3. Замыкания
- •8.4. Абстрактный подход
8.2. Способы композиции функций
Функции первого порядка:
обыкновенный вызов
(defun f ... (g ...) ...)
рекурсивный вызов
(defun f ... (f ...) ...)
вложенный рекурсивный вызов
(defun f ... (f ... (f ...) ...) ...)
Функции более высокого порядка:
функциональный аргумент
(defun f (... g ...) ... (apply g ...) ...)
рекурсивный функциональный аргумент
(defun f (... g ...) ...(apply g ... g ...) ...)
Получающий себя в качестве аргумента функционал называют применяемым к самому себе или автоаппликативной (самоприменяемой) функцией. Соответственно функцию, возвращающую саму себя, называют авторепликативной (самовоспроизводящей) функцией.
Автоаппликативные и авторепликативные функции образуют класс автофункций.
Применяющие функционалы позволяют применять функциональный аргумент к другим параметрам. Применяющие функционалы дают возможность интерпретировать и преобразовывать данные в программу и применять ее в вычислениях.
APPLY применяет функцию к списку аргументов
(APPLY fn список) <==> (fn ‘x1 ‘ x2 ... ‘xn)
где список = (x1 x2 ... xn)
Функция fn не должна быть встроенной функцией or или and.
(apply ‘+ ‘(2 3)) ==> 5
(setq f ‘+)
(apply f ‘(2 3)) ===> 5
(apply ‘eval ‘(+ 2 3)) ==> 5
(apply ‘apply ‘(+ (2 3))) ==> 5
(apply ‘(lambda (x y) (+ x y)) ‘(2 3)) ==>5
Использование APPLY дает большую гибкость по сравнению с прямым вызовом функции: с помощью одной и той же функции APPLY можно в зависимости от функционального аргумента осуществлять различные вычисления.
FUNCALL вызывает функцию с аргументами
Аргументы для вызываемой функции funcall принимает не списком, а по отдельности.
(funcall fn x1 x2 ... xn) <==> (fn x1 x2 ... xn)
Функция fn не должна быть встроенной функцией or или and.
(funcall ‘list ‘apply ‘‘+ ‘‘( 2 3)) ==> (apply (quote +) (quote (2 3)))
(defun do (x f1 f2)
(funcall (if (< x 0) f1 f2) x))
(do -1 ’- ’(lambda (x) (* x x x))) ==> 1
(do 4 ’- ’(lambda (x) (* x x x))) ==> 64
Отображающие функционалы повторяют применение функции: отображают список в новый список.
Mapcar - применяет функцию к последовательным элементам списка
Синтаксис : (mapcar <fcn> <list1> <list2>...)
Применяет функцию к последовательным элементам списков:
<fcn> - функция или функциональное имя,
<listn> - список для каждого аргумента функции.
Возвращает список значений функции.
(mapcar ‘1+ ‘(1 2 3)) ==> (2 3 4)
(mapcar ‘(lambda (x) (* 2 (1+ x))) ‘(1 2 3)) ==> (4 6 8)
(mapcar ‘+ ‘(1 2 3) ‘(5 6 7)) ==> (6 8 10)
(mapcar ‘list ‘(+ + +) ‘(1 2 3) ‘(a b c)) ==> ((+ 1 a) (+ 2 b) (+ 3 c))
(mapcar ’evenp ‘(1 2 3 4)) ==> (nil t nil t)
(mapcar ’equal ‘(1 2 3) ‘(1 4 9 16)) ==> (t nil nil)
(mapcar ’max ‘(1 2 3 4) ‘(1 4 9 16) ‘(11 1 2 10)) ==> (11 4 9 16)
Функционал mapcar с одноместной функцией в качестве функционального аргумента можно определить так:
(defun map (f x)
(if (null x) nil
(cons (funcall f (first x)) (map f (rest x)))
)
)
MAPLIST повторяет вычисления на хвостовых частях списка; действует подобно mapcar, но действия осуществляет не над элементами списка, а над последовательностью хвостов этого списка (начиная с самого исходного списка):
(maplist ‘(lambda (x) x) ‘(a b c)) ==> ((a b c) (b c) (c))
(maplist ‘reverse ‘(a b c)) ==> ((c b a) (c b) (c))
"Универсальный" функционал reduce
(defun reduce (g x a)
(if (null x) a
(funcall g (first x) (reduce g (rest x) a))
)
)
Пусть x - список, состоящий из элементов (x1 x2 x3 x4 ... xn), тогда значение функции (reduce g x a) есть результат вычисления выражения
g ( x1, g ( x2, ... g ( xn, a) ...))
; примеры вызова:
; (reduce '* '(6 4 3) 1)
; (reduce 'max '(6 4 8) 0)
; (reduce 'list '(a b c) nil) => (A (B (C NIL)))
; (reduce ‘(lambda (x y) (list x '+ y)) '(a b c) 'd)
; =>(A + (B + (C + D)))
(defun sumpr (s)
(list (reduce ’+ s 0)
(reduce ’* s 1)))