1пгснч. Виды языков программирования. Виды языков программирования Парадигмы программирования
Скачать 221.52 Kb.
|
Виды языков программирования Парадигмы программирования Парадигма — это главная идея какого-либо сложного понятия (в данном случае языка программирования). Применительно к языкам программирования различают следующие парадигмы: императивное программирование; функциональное программирование; логическое программирование; объектно-ориентированное программирование. В императивном программировании задание для компьютера формируется в виде последовательности команд, в функциональном программировании — указанием функций. В логическом программировании применяются высказывания, а в объектно- ориентированном программировании — объекты. Каждую парадигму поддерживает свой вид языков программирования: Императивные ЯП ориентированы на операторы. Вычисления в них представляются как последовательность действий, производимых операторами. Функциональные ЯП задают вычисления как вызовы функций. Логические ЯП описывают вычисления с помощью формальной логики. В объектно-ориентированных ЯП вычисления реализуются совокупностью объектов. Конечно, весьма наивно классифицировать языки программирования только по одному основанию — парадигме, поэтому в данной лекции приведен обзор и языков разметки, и скриптовых языков. Языки разметки, например HTML, не являются языками программирования. Эти языки не описывают вычислений, а всего лишь задают общий вид документа. Тем не менее к языкам разметки применимы критерии оценки, приведенные в первой главе. В частности, совершенно очевидна важность читабельности и легкости создания кодов разметки. Императивные языки программирования Императивные (процедурные) языки программирования (ЯП) задают вычисления как последовательность команд (операторов). Они ориентированы на компьютеры с архитектурой фон Неймана. Основные понятия императивных ЯП тесно связаны с компонентами компьютера: переменные различных типов (моделируют ячейки памяти); операторы присваивания (моделируют пересылки данных); повторения действий в форме итерации (моделируют хранение информации в смежных ячейках памяти). При реализации оператора присваивания происходит следующее: операнды выражения передаются из памяти в процессор, а результат вычисления выражения заносится в ячейку памяти, именуемую левой частью оператора. Поскольку операторы хранятся в соседних ячейках памяти, то итерации на компьютере фон Неймана осуществляются очень быстро. Вычисления основываются на понятии состояние компьютера. Состояние компьютера — это множество всех значений всех ячеек его памяти. Программа состоит из последовательности операторов, выполнение каждого из которых влечет за собой изменение значения в одной или нескольких ячейках памяти, то есть переход компьютера в новое состояние. В общем случае синтаксис императивной программы имеет вид: оператор1; оператор2; … Чаще всего операторы выполняются в порядке их следования в программе, друг за другом, и приводят к последовательной смене состояний компьютера. Конечное состояние обеспечивает требуемый результат. Словом, императивные программы гармонизированы с принципами работы традиционного компьютера, реализуются быстро и эффективно. Именно этим объясняется высокая популярность императивных ЯП. Императивные языки: C. Функциональные языки программирования Аппликативный подход к вычислениям, в отличие от императивного подхода, основывается на собственной идее. Вместо отслеживания последовательности состояний, через которые должен пройти компьютер для получения ответа, здесь ищется функция программы, обеспечивающая ожидаемый результат. Внимание концентрируется на последовательных преобразованиях начальных данных с помощью функций. Как только будет придуман конечный ответ (последовательность функций), его можно применить к начальным данным и получить результат. Функциональные (аппликативные) языки задают вычисления как вызовы функций. Синтаксис функциональной программы выглядит следующим образом: functionn(…function2(function1(данные))…) В начале вычислений к исходным данным применяется функция function1, затем к полученному промежуточному результату — function2 и т. д. В последнюю очередь применяется функция functionn. Она возвращает ожидаемый результат. Таким образом, в функциональных языках отсутствуют переменные (в том смысле, который им придается в императивных языках), нет операторов присваивания, нет повторений в форме итераций. Чтобы определить функцию, нужно придумать ее имя и задать вычисляемое ей выражение. Описание единичного действия — это вызов функции с конкретными аргументами. Описание программы — это описание последовательности вызовов отдельных функций. Обсудим преимущества и недостатки функционального программирования. Прежде всего, функциональные программы предлагают предельно естественную, математическую форму записи вычислений. Программы получаются короткими, выразительными и понятными. Здесь доминирует более высокий уровень программирования, требующий меньших усилий, чем императивное программирование. Программист свободен от необходимости учитывать те детали, которыми наполнена императивная программа. Однако за высокий уровень абстракции приходится расплачиваться проблемами реализации. В функциональном языке программисту не нужно связываться с переменными, поскольку здесь не требуются такие абстракции, как ячейки памяти. Для организации повторения действий используется мощный механизм рекурсии, тоже оставляющий в стороне детали реализации. Все это выливается в большие накладные расходы времени и памяти при выполнении программы. Компьютер с последовательным порядком работы и линейной организацией памяти просто не способен обеспечить высокую эффективность функциональных вычислений. Примерами функциональных языков являются LISP (Clojure), Haskell, Scala, R. Логические языки программирования Логические (декларативные) языки описывают не способ решения задачи, а саму задачу. Фактически они задают формализованное представление предметной области. Иногда логические языки называют языками, основанными на системе правил. Здесь осуществляется проверка некоторого разрешающего высказывания (утверждения), и в случае его истинного значения выполняется соответствующее действие. В императивном языке программирования вычисления описываются очень подробно, с обязательным указанием порядка выполнения операторов. В языке, основанном на системе правил, не существует определенного порядка применения правил, и система реализации языка должна сама выбрать нужный порядок выполнения действий, который приведет к желаемому результату. Такая парадигма программирования радикально отличается от парадигм, используемых в остальных трех видах языков программирования, и, безусловно, требует абсолютно иной языковой поддержки. Синтаксис программ для логических языков выглядит следующим образом: действие1 :- разрешающее высказывание1 действие2 :- разрешающее высказывание2 … действиеn :- разрешающее высказываниеn Подчеркнем еще раз: действия осуществляются не в той последовательности, в которой они определены в программе. Порядок выполнения определяют разрешающие высказывания, которые, по сути, являются предикатами первого порядка. Самым известным языком логического программирования является Prolog. Объектно-ориентированные языки программирования Парадигма объектно-ориентированного программирования является развитием императивного программирования. При ее создании преследовались две цели: сократить размеры программ за счет повышения размера строительных элементов ( ≪маленькие≫ переменные заменяются ≪большими≫ объектами) и тем самым обеспечить возможность создания (за то же время) более крупных программных приложений; упростить процесс создания новых программ на базе старых (за счет применения механизма наследования). Объектно-ориентированные языки впитали в себя лучшие понятия и механизмы императивных языков. Объектно-ориентированные языки задают вычисления как взаимодействия программных объектов. Объект — это именуемый модуль, заключающий в себе данные и операции для их обработки. Программный объект во многом похож на физический объект реального мира. В частности, программный объект имеет свое состояние и демонстрирует окружающей среде свое поведение. Состояние объекта характеризуется перечнем данных и их значений. Поведение задается последовательностью выполняемых операций. Объекты взаимодействуют друг с другом с помощью сообщений. Посылается сообщение объектом-источником в адрес объекта-приемника. Каждое сообщение — это запрос на выполнение операции объектом-приемником. Описание объектов с общей структурой и поведением называется классом. Как и переменные, единичные объекты создаются по их описаниям. Только в роли описаний для переменных выступают типы данных, а в роли описаний для объектов — классы. Объект считается экземпляром класса. Специфику объектно-ориентированного подхода определяют три принципа: инкапсуляция (сокрытие своего содержимого от внешнего мира); наследование (возможность получения потомками структуры и поведения предков); полиморфизм (использование одного и того же имени для выражения различных действий и объектов). Инкапсуляция означает, что каждый объект помещен в защитную оболочку, сквозь которую другие объекты видят лишь самое необходимое: заголовки операций, которые может выполнять объект. Наследование позволяет внедрить в новый класс элементы данных и операции старого класса, обеспечивая возможность их модификации. Наконец, полиморфизм поддерживает возможность существования целого семейства различных операций с одинаковым именем. Язык C# Скриптовые языки Традиционные языки программирования предназначены прежде всего для создания автономных приложений: программ, которые принимают входные данные, обрабатывают их определенным образом и генерируют соответствующие результаты. Однако в большинстве компьютерных приложений требуется координация множества программ. В большой платежной системе, например, должны обрабатываться данные от устройств чтения кредитных карточек, сканируемых бумажных форм а также данные, вводимые вручную с клавиатуры. Здесь выполняются тысячи запросов к базе данных; реализуются сотни юридических и корпоративных правил; создается обширная документация для сохраняемых записей, аудита, налоговых отчислений; распечатываются ведомости по зарплате; поддерживается связь с серверами по всему миру для обеспечения депозитов в режиме ≪онлайн≫, налогового обслуживания, изъятия накоплений, медицинского страхования и т. д. Эти задачи, вероятно, требуют применения сотен отдельных программ. Координация этих программ бесспорно потребует разнообразных проверок и логических решений, циклов, переменных и типов, подпрограмм и абстракций — тех же видов логических утилит, которые традиционные языки предоставляют внутри приложения. В гораздо меньших масштабах художник-график или фотокорреспондент загружает изображения из цифровой камеры, конвертирует их в любимый формат, вращает изображения для выбора оптимальной ориентации, индексирует их по времени, теме и цветовой гамме, перемещает в удаленный архив, а затем повторно инициализирует память камеры. Ручное выполнение этих шагов, вероятно, будет и утомительно, и подвержено ошибкам. В подобном стиле создание динамической веб-страницы может требовать идентификации и авторизации, поиска в базе данных, отображения манипуляций, удаленного взаимодействия, чтения и записи текста HTML. Сценарии подобных действий принято называть скриптами. Все эти сценарии обосновывают потребность в программах, которые координируют другие программы. Традиционные языки повышают эффективность, сопровождаемость, мобильность и возможность статического обнаружения ошибок. Их системы типизации создаются на основе таких понятий аппаратного уровня, как целые числа фиксированного размера, числа с плавающей запятой, символы и массивы. Напротив, скриптовые языки ориентированы на повышение гибкости, скорости разработки, локализацию и динамическую проверку (в период выполнения). Их системы типизации включают в себя такие понятия высокого уровня, как таблицы, шаблоны, списки и файлы. Универсальные скриптовые языки, такие как Perl и Python, иногда называют склеивающими языками, поскольку они создавались для ≪склеивания≫ существующих программ в интересах создания большой системы. С ростом Всемирной паутины скриптовые языки получили новый толчок в направлении генерации динамического информационного наполнения сети. Они также широко используются как языки расширения, которые позволяют пользователю настраивать или расширять функциональные возможности ≪скриптовых≫ утилит. |