- •Функциональное и логическое программирование
- •Глава 1. Классификация языков и стилей программирования 3
- •Глава 2. Программирование на языКе лисп 16
- •Глава 3. Программирование на языке пролог 89
- •Глава 1. Классификация языков и стилей программирования
- •Основные парадигмы программирования
- •Процедурное (императивное, директивное) программирование.
- •Объектно-ориентированное программирование.
- •Декларативное программирование
- •Логическое программирование.
- •Функциональное программирование.
- •Классификация языков программирования
- •Функциональные языки
- •Логические языки
- •Глава 2. Программирование на языКе лисп
- •История создания языка Лисп
- •Диалекты языка Лисп
- •Лисп-машины
- •Область применения языка Лисп
- •Особенности языка Лисп Одинаковая форма данных и программ
- •Хранение данных, не зависящее от места
- •Автоматическое и динамическое управление памятью
- •Функциональная направленность
- •Динамическая проверка типов
- •Интерпретирующий и компилирующий режимы работы;
- •Пошаговое программирование
- •Единый системный и прикладной язык программирования
- •Основы языка Лисп
- •Понятие функции.
- •Quote блокирует вычисления
- •Базовые функции языка.
- •Функция car возвращает в качестве значения первый элемент списка.
- •Функция cdr - возвращает в качестве значения хвостовую часть списка, т. Е. Список, получаемый из исходного списка после удаления из него головного элемента:
- •Функция cons включает новый элемент в начало списка:
- •Предикат equal проверяет идентичность записей:
- •Предикат equalp проверяет наиболее общее логическое равенство:
- •Другие простейшие встроенные функции Лиспа. Функция null проверяет, является ли аргумент пустым списком:
- •Комбинации вызовов car и cdr позволяют получить любой элемент списка:
- •Наиболее общая функция, выделяющая n-й элемент списка (при этом индексация начинается с 0):
- •Функция last позволяет выделить последний элемент списка:
- •Функция list - создает список из элементов:
- •Функция setq – невычисляющее присваивание:
- •Функция setf - обобщенная функция присваивания:
- •Функции, обладающие побочным эффектом, называются псевдофункциями.
- •С символом можно связать именованные свойства:
- •Функция get - возвращает значение свойства, связанного с символом:
- •Псевдофункция remprop удаляет свойство и его значение:
- •Вызов интерпретатора eval вычисляет значение выражения.
- •Ввод и вывод.
- •Использование файлов.
- •Определение функций
- •Задание параметров в лямбда-списке.
- •Передача параметров и область их действия.
- •Вычисления в лисПе.
- •Предложение let создает локальную связь внутри формы:
- •Последовательные вычисления.
- •Разветвление вычислений.
- •Циклические вычисления.
- •Передача управления.
- •Другие циклические структуры.
- •Динамическое управление из другого контекста
- •Внутреннее представление списков
- •Функциональное программирование Рекурсия. Различные виды рекурсии.
- •Функции более высокого порядка.
- •Применяющие функционалы.
- •Отображающие функционалы.
- •Макросы
- •Типы данных
- •Основные типы данных:
- •Глава 3. Программирование на языке пролог
- •Общие сведения о языке Пролог. Язык Пролог как система, реализующая логический вывод в исчислении предикатов первого порядка.
- •Фразы Хорна как средство представления знаний.
- •Синтаксис языка Пролог.
- •Фразы, термы, факты, правила.
- •Константы:
- •Простейшая программа на Прологе
- •Выполнение запроса в Прологе.
- •Неудача запроса и возврат назад.
- •Декларативная и процедурная семантика Пролога.
- •Рекурсивные процедуры.
- •Списки.
- •Операторы.
- •Средства управления ходом выполнения программы. Предикат сократить (отсечение).
- •Отрицание как неудача запроса.
- •Встроенные предикаты.
- •Типы отношений.
- •Ограничения, обеспечивающие целостность отношений.
- •Свойства отношений.
- •Подходы к программированию на языке Пролог.
Другие циклические структуры.
Бесконечный цикл:
(LOOP m1 m2 … mn)
Циклически вычисляются формы m1, …, mn. Выход из цикла с помощью оператора RETURN.
(loop (setq x (read)) (cond ((equal x 'end) (return 'end)) (t nil)) (print x))
Ввод: 2
Вывод 2
Ввод end
END (Выход из цикла)
Форма DOTIMES используется, если цикл надо выполнить некоторое число раз:
(dotimes (var count-form result form) форма1 форма2..)
dotimes вычисляет count-form, значение должно быть целым. Если count-form равно 0 или отрицательно цикл не выполняется. Цикл выполняется от 0 до (count-form-1). Переменная цикла var связывается со значением count-form. После выполнения цикла связь var восстанавливается. Если нет результирующей формы выводится NILL.
Пример.
(dotimes (x (+ 1 2)) (print x))
=> 0
1
2
NIL
(dotimes (x (+ 1 2) (setq x 100)) (print x))
=> 0
1
2
100
Форма DOLIST используется, если цикл надо выполнить с каждым элементом списка:
dolist(var list-форма [result-форма]) форма1 форма2…)
Пример.
dolist (x '(a b c d)) (prin1 x))
=> A B C D
=> NIL
Динамическое управление из другого контекста
До сих пор рассматривались структуры, вычисление которых проводится в одном статическом контексте. В некоторых случаях возникает необходимость прекратить вычисление функции динамически из другого контекста и выдать результат в более раннее состояние, не осуществляя нормальную последовательность возвратов из всех вложенных вызовов. Такая необходимость может возникнуть, например, при обнаружении ошибки. Динамическое прерывание вычисление моно запрограммировать с помощью форм CATCH (поймать) и THROW (бросить):
(CATCH метка форма1 форма2 …) (THROW метка значение)
Выполняется следующая последовательность операций:
вычисляется метка;
вычисляются формыi слева направо;
если не встретилась форма THROW, значение последней выполненной формы возвращается в качестве значения формы CATCH;
если встретилось форма THROW и ее аргумент «метка» равен метке в форме CATCH, то управление передается в CATCH и значением формы становится значение аргумента THROW.
Пример:
(catch 'dummy-tag 1 2 (throw 'dummy-tag 3) 4) => 3
(catch 'dummy-tag 1 2 3 4) => 4
(catch (setq x 5) 1 2 3 (throw (+ 1 4) 8) 9 0) = > 8 - метки вычисляются в отличие от формы GO.
(setq x (catch (setq x 5) 1 2 3 (throw (+ 1 4) 8) 9 0)) => 8
x =>8
Управление передается внутри формы, а не завершается выходом из нее, как при использовании RETURN.
Форма BLOCK устанавливает блок с именем name, затем последовательно выполняет формы подобно PROGN:
(BLOCK name form1 ….formn)
(return-fROM name форма-значение)
Если не встретилось retutn-from, возвращается значение последней формы. Если return-from не содержит формы значения, возвращается nill, в противном случае – значение формы return-from.
Формы BLOCK и return-FROM работают совместно, обеспечивая выход на более высокий уровень. В любой точке любой из форм, входящих в блок, может быть использована функция return-from, чтобы передать управление из BLOCK -формы и значение формы. Исключение составляет случай, если определен внешний BLOCK с тем же именем, что и внутренний. В этом случае управление передается внутреннему блоку.
Примеры.
Пустой блок
(block empty) => nill
Блок без передачи управления
(block stop (+ 1 2) (+ 3 4)) => 7
Блок с передачей управления
(setq x 1)
(block stop (setq x 2) (return-from stop) (setq x 3)) => nill - без передачи результата
x => 2
(block stop (return-from stop (+ 1 2)) (+ 3 4)) => 3 - с передачей результата
Выход на верхний уровень
(block outer (block inner (return-from outer 1)) 2) => 1
Выход из внутреннего блока и нормальное завершение внешнего блока
(block twin (block twin (return-from twin 1)) 2) => 2
