- •Тема 1. Функциональная парадигма в программировании
- •1.1. Общие сведения о парадигмах программирования
- •1.2. История функционального программирования
- •1.3. Основы функционального программирования
- •1.3.2. Строгая типизация
- •1.3.3. Модульность
- •1.3.4. Функции — это значения и объекты вычисления
- •1.3.5. Чистота (отсутствие побочных эффектов)
- •1.3.6. Отложенные (ленивые) вычисления, виды вычислений (вызовы по значению и по необходимости)
- •1.3.7. Строгие функции
- •Список литературы
- •Лабораторная работа №1
- •Начало работы с Hugs
- •Установка программы
- •Команды Hugs
- •Просмотр классов
- •Просмотр зарегистрированных имён объектов
- •Просмотр конструкторов типов
- •Просмотр иерархии классов
- •Создание скрипта
- •Некоторые важные понятия
- •Упражнение.
- •Изучение файла Prelude.Hs
- •Выполнение работы
- •Задания
- •Требование нетривиальности в данном случае означает, что встречающиеся в выражениях списки должны содержать больше одного элемента. Контрольные вопросы
Тема 1. Функциональная парадигма в программировании
1.1. Общие сведения о парадигмах программирования
За те пятьдесят с небольшим лет, которые существует дисциплина: программирование", - сменилось несколько поколений правил, концепций, моды, взглядов на то, как надо "писать программы". Все эти правила, концепции, взгляды, мода, наконец, позже назвали в информатике "парадигмами программирования". Вот неполный список парадигм, вместе с датами их появления:
1957г., процедурная парадигма, язык ФОРТРАН, создатель Бэкус;
1967г., функциональная парадигма, язык ЛИСП, создатель Маккарти;
1970г., структурированная парадигма, язык ПАСКАЛЬ, создатель Вирт;
1974г., логическая парадигма, язык ПРОЛОГ;
1983г., объектно-ориентированная парадигма, пример - язык C++, создатель Страуструп.
В конце списка представлены языки программирования и их создатели, внесшие значительный вклад в популяризацию этих парадигм.
В процессе своего развития эти парадигмы "мутировали", "отпочковывались", объединялись" (так, язык Си объединил в себе процедурную и структурированную парадигму). В результате этих "мутаций" по состоянию на 01.06.2008 года оформились следующие парадигмы программирования:
Процедурная (или модульная) парадигма;
Логическая парадигма;
Объектно-ориентированная парадигма.
Эти три совершенно разные по подходу парадигмы составляют основу современного программирования. Хотя в настоящее время наиболее "модной" является объектно-ориентированная парадигма, остальные парадигмы также используются на практике и изучаются в ВУЗах.
Прежде чем начать описание собственно функционального программирования, необходимо обратиться к истории науки о программировании.
1.2. История функционального программирования
Широко известно, что теоретические основы императивного программирования были заложены еще в 30-х годах XX века учёными Аланом Тьюрингом и Джоном фон Нейманом. Теория, положенная в основу функционального подхода, также родилась в 20-х – 30-х годах XXстолетия. В числе разработчиков математических основ функционального программирования можно назвать Мозеса Шёнфинкеля (Германия и Россия) и Хаскелла Карри (Англия), разработавших комбинаторную логику, а также Алонзо Чёрча (США), создателя-исчисления.
Теория так и оставалась теорией, пока в начале 50-х годах XXвека Джон МакКарти не разработал язык Lisp [1], [10], [12], который стал первым почти функциональным языком программирования и на протяжении многих лет оставался единственным. Хотя Lisp все еще используется (как, например, и FORTRAN), он уже не удовлетворяет некоторым современным запросам, которые заставляют разработчиков программ взваливать как можно большую ношу на компилятор, облегчив тем самым свой непосильный труд. Необходимость в этом, конечно же, возникла из-за всё более возрастающей сложности программного обеспечения.
В связи с этим всё большую роль начинает играть типизация. В конце 70-х – начале 80-х годов XX века интенсивно разрабатываются модели типизации, подходящие для функциональных языков. Большинство этих моделей включали в себя поддержку таких мощных механизмов, как абстракция данных и полиморфизм. Появляется множество типизированных функциональных языков: ML, Scheme, Hope, Miranda, Clean и многие другие. Вдобавок постоянно увеличивается число их диалектов, применяемых для решения конкретных задач.
В результате вышло так, что практически каждая группа исследователей, занимающаяся функциональным программированием, использовала собственный язык [13], [14]. Это препятствовало дальнейшему распространению этих языков и порождало многочисленные более мелкие проблемы. Чтобы исправить ситуацию, объединенная группа ведущих исследователей в области функционального программирования решила воссоздать достоинства различных языков в новом универсальном функциональном языке. Первая реализация этого языка, названного Haskell в честь Хаскелла Карри, была создана в начале 90-х годов. В настоящее время действителен стандарт Haskell-98 [2].
В первую очередь, большинство функциональных языков программирования реализуются как интерпретаторы, следуя традициям языка Lisp. Интерпретаторы удобны для быстрой отладки программ, исключая длительную фазу компиляции, тем самым укорачивая обычный цикл разработки. Однако с другой стороны, интерпретаторы в сравнении с компиляторами обычно проигрывают по скорости выполнения в несколько раз. Поэтому помимо интерпретаторов существуют и компиляторы, генерирующие неплохой машинный код (например, Objective Caml) или код на C/C++ (например, Glasgow Haskell Compiler). Практически каждый компилятор с функционального языка реализован на этом же языке.
В данном методическом пособии будет рассмотрена реализация стандарта Haskell-98 в виде интерпретатораHUGS 98.