- •Содержание
- •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. Абстрактный подход
2.2. Примеры программ
; Определения и использования функций, символ ";" обозначает,
; что дальше до конца строки следует комментарий
; square - возведение в квадрат
(defun square (x) (* x x))
; (max x y) - наибольшее из двух чисел
(defun max (x y)
(if (> x y) x y)
)
; (max3 x y z) - наибольшее из трех чисел
(defun max3 (x y z) (max x (max y z)))
;(div m n) -целочисленное деление
(defun div (m n) (truncate (/ m n)))
; intDiv(m n) -> ( m div n, m mod n)
(defun intDiv (m n)
(list (div m n) (mod m n))
)
;"r -действительное число" (analyse r) -> список из трех элементов:
; 1) знак "-" или "+" в зависимости от того, меньше или больше
; число r числа 0;
; 2) значение истинности (T и NIL), показывающее,
; принадлежит ли данное число r диапазону |r| <= 1;
; 3) "ближайшее" целое число к данному
(defun analyse (r)
(list (if (< r 0) '- '+)
(<= (abs r) 1)
(round r)
)
)
; рекурсивная функция для вычисления суммы первых n целых чисел
(defun sum (n)
(if (= n 0) 0 (+ n (sum (- n 1))))
)
2.3. Символьная обработка
Традиционные машины (фон Неймана) и языки программирования первоначально разрабатывались для осуществления численных вычислений и обработки больших объемов данных и не подходят столь же хорошо для символьной обработки, которая имеет дело со сложными структурами данных и базами знаний, содержащими правила принятия решений и другие многообразные объекты. Символьная обработка позволяет эффективно работать с такими структурами, как предложения естественного языка, значения слов и предложений, нечеткие понятия и т. д., и на их основе принимать решения, проводить рассуждения и осуществлять другие, свойственные человеку способы обращения с данными.
В этих применениях предполагается представление в подходящей форме символьных и сложно структурированных данных и работа с ними часто ведется в заранее непредсказуемых ситуациях.
Лисп является наиболее важным языком программирования, используемым в исследованиях по искусственному интеллекту и в математической лингвистике. Название языка “Лисп” происходит из “listing processing” (обработка списков).
Лисп опередил свое время. Обычно языки программирования не изобретают, а проектируют. Однако по отношению к Лиспу можно говорить об изобретении. Первоначальная версия языка, в частности, содержала множество понятий и принципов, которые казались очень странными, но многие из которых позже оказались существенным нововведением. Кроме этого, возможность добавления в Лисп в течение десятилетий многих новых черт подтвердила свойство расширяемости этого языка. Вокруг Лиспа возникла широкая культура, охватывающая различные школы и разнообразные диалекты языка, различные системы и методы программирования, программные среды и Лисп-машины.
2.4. Особенности Лиспа
Одинаковая форма данных и программы. И то, и другое представляется списочной структурой, имеющей одинаковую форму. Таким образом, программы могут обрабатывать и преобразовывать другие программы и даже самих себя. Можно введенное и сформированное в результате вычислений выражение данных проинтерпретировать в качестве программы и непосредственно выполнить (так называемое программирование, управляемое данными). Универсальный единообразный и простой лисповский синтаксис списка не зависит от применения, и с его помощью легко определять новые формы записи, представления и абстракции. Даже сама структура языка является, таким образом, расширяемой и может быть заново определена. В то же время достаточно просто написание интерпретаторов, компиляторов, преобразователей, редакторов и других средств.
Хранение данных, не зависящее от места. Списки, представляющие программы и данные, состоят из списочных ячеек, расположение и порядок которых в памяти не существенны. Структура списка определяется логически на основе имен символов и указателей.
Автоматическое и динамическое управление памятью. Пользователь не должен заботиться об учете памяти. Система резервирует и освобождает память автоматически в соответствии с потребностью. Когда память кончается, запускается специальный мусорщик. Он собирает неиспользуемые символы и списки, включает их в работу путем вторичного использования. Среда Лиспа постоянно содержится в порядке.
Лисп - безтиповой язык программирования. В Лиспе имена символов, переменных, списков, функций и других объектов не закреплены предварительно за какими-нибудь типами данных. Типы в общем не связаны с именами объектов данных, а сопровождают сами объекты. Таким образом, переменные могут в различные моменты времени представлять различные объекты разных типов.
Заблуждения и предрассудки. А. П. Ершов: “Чувство протеста - вы раз за разом будете ощущать себя как спортсмены, которым нужно играть в волейбол с одной рукой, привязанной к телу. Ощущение трудности и необычности составления функциональных программ вполне законно и естественно”. Мы - жертвы императивного программирования и машин фон Неймана. Естественно, используемые в программировании на Лиспе структуры данных и управляющие структуры часто сложны, поскольку проблемы искусственного интеллекта из-за своей сложности предполагают сложные структуры и программы. Иерархические списочные структуры и Лисп как раз и задумывались для работы со сложными проблемами. Искусственное упрощение структур означало бы пренебрежение действительной сложностью проблем. Новая парадигма - объектно-ориентируемое программирование в Лиспе.