Статья/Физика и математика – Информатика и кибернетика

УДК 004.43

, ,

Парадигмы и языки
в обучении информатике и программированию

МГУ им. , факультет ВМК

Дается обзор основных парадигм, или стилей программирования: императивного, функционального, логического и объектно-ориентированного. Обсуждается необходимость изучения средств каждой из этих парадигм в рамках высшего образования в области информатики и программирования.

Ключевые слова: парадигмы программирования, стили программирования, языки программирования, обучение программированию

Введение

Основные стили, или парадигмы программирования, к которым обычно относят императивное, функциональное, логическое и объектно-ориентированное программирование [1, 6], возникли более сорока лет назад вместе с первыми языками программирования и развивались сначала относительно независимо друг от друга. Каждая из парадигм отображает определенную модель вычислений, включая структуры данных и механизмы управления, и с ней связан определенный класс прикладных задач, которые удобно решать средствами данной парадигмы.

В настоящий момент большинство современных языков программирования [3, 4] обычно включают средства и приёмы программирования различных парадигм, хотя классифицируются согласно средствам своего ядра (к примеру, язык программирования Лисп – функциональный язык, хотя включает некоторые конструкции императивного стиля). Тем самым все более сложным становится выбор языка для обучения программированию в высшей школе.

НЕ нашли? Не то? Что вы ищете?

В данной работе дается краткий обзор и сравнение основных парадигм программирования и показывается, что полноценное образование в области информатики и программирования предполагает освоение базовых приемов всех парадигм путем изучения языков, являющихся типичными представителями своей парадигмы.

Парадигмы программирования

Императивная, или процедурная парадигма программирования является наиболее известной [6]. Она развилась на базе низкоуровневых языков (машинные коды, ассемблер), основанных на архитектуре фон Неймана. Императивная программа состоит из последовательно выполняемых команд и вызовов процедур, которые обрабатывают данные и изменяют значения переменных программы. Переменные при этом рассматриваются как некоторые контейнеры для данных, подобно ячейкам памяти компьютера.

Функциональная парадигма программирования [5] является менее традиционной, и в тоже время более древней, поскольку получила развитие из вычислений по алгебраическим формулам. Функциональная программа состоит из набора взаимосвязанных и, как правило, рекурсивных функций. Каждая функция определяется выражением, которое задает правило вычисления её значения в зависимости от значений ее аргументов. Выполнение функциональной программы заключается в последовательном вычислении значений функциональных вызовов.

В еще менее традиционной и необычной логической парадигме программа рассматривается как множество логических формул: аксиом (фактов и правил), описывающих свойства некоторых объектов, и теоремы, которую необходимо доказать [2]. В свою очередь, выполнение программы – это доказательство теоремы, в ходе которого строится объект с описанными свойствами.

Основные различия указанных парадигм касаются не только концепции программы, но и роли переменной. В отличие от императивных программ, в функциональных и логических программах отсутствует явное присваивание значений переменным и, как следствие, побочные эффекты. Переменные в таких программах подобны переменным в математике: они являются обозначением функциональных аргументов или объктов, конструируемых в процессе доказательства. Еще одна яркая особенность функциональной и логической парадигм – использование рекурсии вместо циклов.

В получающей все большее распространение объектно-ориентированной парадигме программа описывает структуру и поведение вычисляемых объектов и классов объектов [7]. Объект обычно включает некоторые данные (состояние объекта) и операции с этими данными (методы), описывающие поведение объекта. Классы представляют множество объектов со схожей структурой и схожим поведением. Обычно описание классов имеет иерархическую структуру, включающую полиморфизм операций. Выполнение объектно-ориентированной программы представляет собой обмен сообщениями между объектами, в результате которого они меняют свои состояния.

Характерные свойства основных парадигм программирования представлены в Таблице 1.

Таблица 1.

Свойства парадигм программирования

Парадигма

Ключевой концепт

Программа

Выполнение программы

Результат

Императивная

Команда

Последова-тельность команд

Исполнение команд

Итоговое состояние памяти

Функциональная

Функция

Набор функций

Вычисление функций

Значение главной функции

Логическая

Предикат

Логические формулы

Логическое доказатель-ство

Результат доказатель-ства

Объектно-ориентированная

Объект

Набор классов объектов

Обмен сообщениями между объектами

Результирую-щее состояние объектов

Парадигмы и языки программирования

Поскольку парадигмы существуют и развиваются в рамках языков программирования, которые призваны обеспечивать удобные механизмы решения различных прикладных задач, неизбежна интеграция парадигм. Так, уже в первых императивных алгоритмических языках, таких как Фортран, существовали элементы функционального стиля. В то же время применялись и языки, сохраняющие чистоту своей парадигмы, например, объектно-ориентированный Smalltalk [7] и логический Пролог [2].

Большинство современных языков [3] аккумулируют в себе элементы и приемы нескольких стилей, и тем не менее их можно классифицировать по основному их ядру, реализующему приёмы определенной парадигмы программирования, в частности:

· Императивная парадигма: языки Паскаль, Си, Ада;

· Функциональная парадигма: языки Лисп, Рефал, Плэнер, Schema, Haskel;

· Логическая парадигма: языки Пролог и Datalog;

· Объектно-ориентированная парадигма: Smalltalk, Eiffel.

Хотя Smalltalk, являющийся первым чисто объектно-ориентированным языком программирования, не получил должной известности, его основные идеи (абстрактные типы данных, инкапсуляция данных, полиморфизм операций) легко интегрировались в языки программирования других парадигм, в частности, императивной. Действительно, метод объекта может представлять из себя процедуру или функцию, а отправка сообщения – соответственно вызов процедуры или функции. Именно поэтому объектно-ориентированная парадигма программирования получила широкое распространение с тех пор, как ее средства были включены в популярные императивные языки Си и Паскаль, породив тем самым языки С++ и объектный Паскаль.

Подобным образом из объединения объектно-ориентированной с другими парадигмами возникли объектно-ориентированные варианты других языков программирования, например, язык CLOS – объектно-ориентированный Лисп. В настоящее время существует целый ряд современных языков программирования, в которых объединены две парадигмы:

· Императивная и объектно-ориентированная: C++, C#, Delphi, Java и др.;

· Функциональная и объектно-ориентированная: CLOS, Erlang и др.;

· Логическая и объектно-ориентированная: Object Prolog.

В целом, сравнивая разные языки и парадигмы, следует отметить существенное отличие средств и приёмов традиционной императивной парадигмы программирования от средств и приёмов нетрадиционных парадигм – функциональной и логической. Языки программирования, основанные на нетрадиционных парадигмах, отличаются ещё и методом реализации: программы на таких языках обычно интерпретируются, а не компилируются, как в императивных и императивных объектно-ориентированных языках. Еще одно важное их отличие – они ориентированы на символьную обработку данных, поскольку средства этих языков включают:

· древесные структуры данных, такие как списки Лиспа или термы Пролога;

· встроенный механизм сопоставления с образцом (Рефал, Плэнер, Пролог) и бэктрекинга (Плэнер, Пролог);

· функционалы, или функции высшего порядка (Лисп, Schema, Haskel);

· механизм частичных вычислений (Haskel).

Различия во встроенных структурах и механизмах языков программирования определяют различия в классах решаемых с их помощью прикладных задач. Тем самым, каждая из парадигм имеет свою область применения. Императивные языки удобны как для числовых, так и для символьных вычислений, однако они проигрывают функциональным языкам и Прологу в реализации обработки сложных символьных структур. Функциональное программирование хорошо подходит для символьных преобразований, логическое – для построения дедуктивных баз данных и экспертных систем, но в то же время они неудобны для программирования интерактивных задач или событийно-управляемых приложений. В свою очередь, объектно-ориентированная парадигма подходит для создания интерактивных программ со сложным поведением и интерфейсом, обрабатывающих данные различных типов.

Парадигмы и обучение программированию

Выбор подходящего языка и технологии программирования – ключевой вопрос при разработке современных программных продуктов; часто возникает необходимость использования нескольких языков программирования. Ясно, что универсальному специалисту в области информатики и программирования необходимо производить осознанный подбор языка для конкретной прикладной задачи, а для этого он должен знать базовые средства и приемы всех основных парадигм программирования.

Таким образом, обучение в области информатики и программирования должно включать изучение различных парадигм. В современных условиях, когда существуют сотни различных языков программирования, в том числе – схожих по своим средствам и возможностям, довольно сложным является вопрос о выборе базового языка, на котором ведется обучение. Этот вопрос усложняется тем, что постоянно создаются и внедряются в практику новые языки, а изучить все языки программирования не представляется возможным.

Поскольку не существует языка, в полной мере содержащего возможности всех парадигм, для их изучения необходимо подобрать несколько различных языков программирования. С нашей точки зрения, для каждой из основных парадигм должен быть взят по крайней мере один язык, который охватывает базовые ее средства и является тем самым типичным ее представителем – именно это позволит изучить и освоить во всей полноте средства и приёмы данной парадигмы. На этом принципе построен существующий более 20 лет практикум по программированию кафедры алгоритмических языков факультета вычислительной математики и кибернетики МГУ им. . Выпускники кафедры в своей производственной деятельности быстро осваивают новые языки программирования, что подтверждает верность выбранного принципа.

Дополнительно, в курсы по современным языкам программирования целесообразно включить специальные лекции, посвящённые именно парадигмам программирования, в ходе которых обобщаются свойства языков, рассматриваются характерные свойства парадигм, проводится сравнение их базовых приёмов программирования.

Важность изучения именно парадигм программирования обосновывается также тем, что будущее современных популярных языков программирования нам неизвестно. История развития информатики и программирования показывает, что некоторые языки оказались мертворожденными, другие быстро потеряли свою популярность [3], и подобная участь может постигнуть некоторые из современных языков. В тоже время основные парадигмы программирования остаются неизменными, как и их базовые средства и приемы. Таким образом, изучение парадигм является важной компонентой обучения специалистов в области информатики и программирования.

Заключение

Основные парадигмы программирования существенно отличаются по своим приемам и средствам, а поэтому имеют различные области применения в практике программирования. Поскольку современные языки программирования все больше включают средства разных парадигм, необходимо включать изучение парадигм в основные курсы подготовки специалистов высшей школы в области информатики и программирования.

Литература

1.  Голицина О. Л., Попов  на языках высокого уровня: учебное пособие. – М.:ФОРУМ, 2010.

2.  Клоксин У., Меллиш К. Программирование на языке Пролог. М., 1987.

3.  Пратт Т., Зелковиц М. Языки программирования: разработка и реализация – СПб: Питер, 2002.

4.  Себеста  концепции языков программирования – М.: Изд. дом «Вильямс», 2001.

5.  Филд А., Харрисон П. Функциональное программирование. Мир, 1993.

6.  Флойд Р. Парадигмы программирования \\ Лекции лауреатов премии Тьюринга за первые двадцать лет (1966—1985) – М.: Мир, 1993.

7.  Goldberg A., Robson D. Smalltalk-80 – The Language and It’s Implementation. Addison-Wesley, 1982.