- •Содержание
- •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. Абстрактный подход
5. Математические основы: -исчисление
-исчисление было использовано как средство для описания (чисто синтаксического) свойств математических функций и эффективной обработки их в качестве правил. Функциональные программы построены из “чистых” функций, т. е. функций в математическом смысле, и поэтому нотация -исчисления особенно удобна для формального описания манипулирования функциями и даже в качестве промежуточного кода, в который можно транслировать исходную программу. В действительности функциональные языки программирования часто представляют собой “улучшенные” версии нотации -исчисления в том смысле, что все функциональные программы можно преобразовать в эквивалентные -выражения. Хотя нотация -исчисления проста, она является достаточно мощной, чтобы описать все черты исходного функционального языка.
5. 1. Введение в синтаксис
-исчисление можно рассматривать как язык программирования, хотя оно было создано (Чёрч) в 20-х годах нашего века в период философских исследований в области оснований математики. Главная особенность заключается в том, что оно является языком высшего порядка, т. е. в нём имеются средства описания функций, входные и выходные значения которых также могут быть функциями. Кроме того, оно основано не на концепции множества, как многие другие математические языки, а на понятии функции.
Работая в направлении автоматизации значительной части математического и логического интеллекта, программисты-теоретики сталкиваются с теми же проблемами над которыми логики ломают голову уже 80 лет (например, что такое математическое мышление и как его формализовать?). Поэтому их исследования могут служить полезным источником для программистов.
Два подхода к функциям
1. Дирихле: функция задается графиком - множеством пар < аргумент, значение>.
2. Функция – правило, вычислительное предписание.
С первой точки зрения x^2-4 и (x+2)*(x-2) - разные обозначения одной и той же функции; со второй точки зрения – это разные функции.
Обычная запись f(x) может обозначать как обозначение функции, так и вызов функции с аргументом x. Для более строгого подхода это необходимо различать. Для этого вводятся ламбда-обозначения.
Например, x^2+3 - некоторая функция, зависящая от x. Ламбда-обозначение для этой функции x . x^2+3 . Этой записи соответствует правило:
для любого a (x . x^2 +3) (a) = a^2+3
Выражение x + 2y можно считать как функцию от x (записывается x. x +2y ) и как функцию от y (записывается y. x +2y).
(x. x +2y ) a a+2y
(y. x +2y ) a x+2a
Запись y.x.E понимается как y.(x. E). Поэтому
((y.x. x+2y) a) b (x. x+2a) b b+2a
((x.y. x+2y) a) b (y. a+2y) b a+2b
Мы читаем символ как “функция от” и точку (.) как “которая возвращает”.
Определение -термов
Каждая переменная есть -терм.
Каждая константа есть -терм.
По любым -термам M и N можно построить новый -терм (M N) (обозначающий применение, или аппликацию, оператора M к аргументу N).
По любой переменной x и любому -терму M можно построить новый -терм ( x.M ) (обозначающий функцию от x, определяемую -термом M). Такая конструкция называется -абстракция.
Попросту говоря, -исчисление - это исчисление анонимных (безымянных) функций.
Символ x после называется связанной переменной абстракции и соответствует понятию формального параметра в традиционной процедуре или функции. Выражение справа от точки называется телом абстракции, и, подобно коду традиционной процедуры или функции, оно описывает, что нужно сделать с параметром, поступившим на вход функции.
Тело абстракции может быть любым допустимым -выражением, и поэтому оно также может содержать другую абстракцию, например:
x . y . (x+y)*2
Это выражение читается как “функция от x, которая возвращает функцию от y, которая возвращает (x+y)*2.
Используется соглашение:
запись (...(((x1 . x2 . ... xn . E) a1) a2) ...an)
кратко пишется как (x1 . x2 . ... xn . E) a1 a2 ...an
Для полноты опишем ламбда-нотацию более формально в виде БНФ:
<выражение> ::= <идентификатор> . <выражение> |
<идентификатор> |
<выражение> <выражение> |
(<выражение>) |
<константа>
Набор констант произволен: целые числа, булевы константы, арифметические операции, булевы функции и т. п.