Основы функционального программирования/Вводная лекция: различия между версиями
Содержимое удалено Содержимое добавлено
Ramir (обсуждение | вклад) Нет описания правки |
Ramir (обсуждение | вклад) Нет описания правки |
||
Строка 6:
{{Эпиграф|Функциональное программирование ставит своей целью придать каждой программе простое математическое толкование. Это толкование должно быть независимо от деталей исполнения и понятно людям, не имеющим научной степени в предметной области.|Лоренс Паулсон}}
Перед началом описания непосредственно [[w:Функциональное программирование|функционального программирования]] следует обратиться к истории [[w:Программирование|программирования]] вообще. В 1940-х годах появились первые цифровые [[w:Компьютер|компьютеры]], которые
Но даже ассемблеры не могли стать тем инструментом, которым смогли бы пользоваться многие люди, поскольку мнемокоды всё ещё оставались слишком сложными,
Математические функции выражают связь между
Функциональное программирование, как и [[w:Логическое программирование|логическое программирование]], нашло большое применение в теории [[w:Искусственный интеллект|
== История функционального программирования ==
Как известно, теоретические основы императивного программирования были заложены ещё в [[w:1930-е|1930-х]] годах [[w:Тьюринг, Алан Матисон|Аланом Тьюрингом]] и [[w:Нейман, Джон фон|Джоном фон Нейманом]]. Теория, положенная в основу функционального подхода, также родилась в 20-х — 30-х годах. В числе разработчиков математических основ функционального программирования можно назвать [[w:Шёнфинкель, Мозес|Мозеса Шёнфинкеля]]
Теория так и оставалась теорией, пока в начале 1950-х годов [[w:МакКарти, Джон|Джон МакКарти]] не разработал язык [[w:Лисп|
В связи с этим обстоятельством всё бо́льшую роль начинает играть [[w:Типизация|типизация]]. В конце 70-х — начале 80-х годов XX века интенсивно разрабатываются модели типизации, подходящие для функциональных языков. Большинство этих моделей включали в себя поддержку таких мощных механизмов как [[w:Абстракция данных|абстракция данных]] и [[w:Полиморфизм в языках программирования|полиморфизм]]. Появляется множество типизированных функциональных языков: [[w:ML|ML]], [[w:Scheme|Scheme]], [[w:Hope|Hope]], [[w:Miranda|Miranda]], [[w:Clean|Clean]] и многие другие. Вдобавок постоянно увеличивается число диалектов.
В результате вышло так, что практически каждая группа, занимающаяся функциональным программированием, использовала собственный язык. Это препятствовало дальнейшему распространению этих языков и порождало многие более мелкие проблемы. Чтобы исправить положение, объединённая группа ведущих исследователей в области функционального программирования решила воссоздать достоинства различных языков в новом универсальном функциональном языке. Первая реализация этого языка, названного [[w:Haskell|Haskell]] в честь [[w:
Большинство функциональных языков программирования реализуются как [[w:Интерпретация|интерпретируемые]], следуя традициям Лиспа. Таковые удобны для быстрой отладки программ, исключая длительную фазу [[w:Компиляция|компиляции]], укорачивая обычный [[w:Разработка программного обеспечения|цикл разработки]]. С другой стороны, интерпретаторы в сравнении с компиляторами обычно проигрывают по скорости выполнения. Поэтому помимо интерпретаторов существуют и компиляторы, генерирующие неплохой машинный код (например, [[w:OCaml|Objective Caml]]) или код на [[w:Си (язык программирования)|Си]]/[[w:C++|Си++]] (например, Glasgow Haskell Compiler). Что показательно, практически каждый компилятор с функционального языка реализован на этом же са́мом языке.
Строка 42:
=== Краткость и простота ===
Программы на функциональных языках обычно короче и проще, чем те же самые программы на императивных языках. Сравним программы на [[w:Си (язык программирования)|
'''Пример 1. Быстрая сортировка Хоара на [[w:Си (язык программирования)|Си]]'''
Строка 91:
Кроме того, все операции с [[w:Компьютерная память|памятью]] выполняются автоматически. При создании какого-либо объекта под него автоматически выделяется память. Когда объект выполнит своё предназначение, он вскоре будет также автоматически уничтожен [[w:Сборка мусора|сборщиком мусора]], который имеется в любом функциональном языке.
Ещё одно средство, позволяющее сократить программу,
'''Пример 4. Определение N-ого [[w:Числа Фибоначчи|числа́ Фибоначчи]]'''
Строка 105:
Из современных языков программирования многие суть строго типизированные; это обеспечивает безопасность. Программа, прошедшая проверку типов просто не может выпасть в [[w:Операционная система|операционную систему]] с сообщением, подобным «нарушение доступа», особенно это касается таких языков, как [[w:Си (язык программирования)|Си]]/[[w:C++|Си++]] и [[w:Паскаль|Object Pascal]], где обычно применение [[w:Указатель|указателей]]. В функциональных языках бо́льшая часть ошибок может быть исправлена на стадии компиляции, поэтому стадия отладки и общее время разработки программ сокращаются. Строгая типизация позволяет компилятору оптимизировать программы.
В примере с быстрой сортировкой Хоара
Ещё одно проявление полиморфизма — [[w:Перегрузка функции|перегрузка функций]], позволяющая давать разным, но подобным функциям одинаковые имена. Типичный пример перегруженной операции — обычная [[w:Сложение (математика)|операция сложения]]. Функции сложения для целых чисел и чисел с плавающей точкой различны, но для удобства они носят одно имя. Некоторые функциональные языки помимо параметрического полиморфизма поддерживают и перегрузку операций.
Строка 111:
В языке [[w:C++|Си++]] имеется такое понятие, как шаблон, которое позволяет программисту определять полиморфные функции, подобные <tt>quickSort</tt>. В стандартную библиотеку Си++, — [[w:Standard Template Library|STL]], входит такая функция и множество других полиморфных функций. Но шаблоны Си++, как и родовые функции [[w:Ада|Ады]], на самом деле порождают множество перегруженных функций, которые, кстати, нужно каждый раз компилировать, что неблагоприятно сказывается на времени компиляции и размере кода. А в функциональных языках полиморфная функция <tt>quickSort</tt> — это одна единственная функция.
В некоторых языках, например в [[w:
=== Модульность ===
Строка 119:
=== Функции суть значения ===
В функциональных языках, равно как и вообще в языках программирования и [[w:Математика|математике]], функции могут быть переданы другим функциям в качестве [[w:Аргумент|аргумента]] или возвращены в качестве результата. Функции, принимающие функциональные аргументы, называются [[w:Функция высшего порядка|функциями высших порядков]] или [[w:Функционал|функционалами]]. Самый, пожалуй, известный функционал
<code>square (N) = N * N</code>
Строка 129:
Результатом будет список <tt>[1, 4, 9, 16]</tt>.
=== Чистота ===
(отсутствие побочных эффектов) В императивных языках функция в процессе своего выполнения может читать и
Описывать функции без побочных эффектов позволяет практически любой язык. Однако некоторые языки поощряют или даже требуют от функции побочных эффектов. Например, во многих объектно-ориентированных языках в функцию-член класса передаётся скрытый параметр (чаще он называется <tt>this</tt> или <tt>self</tt>), который эта функция неявно
В чистом функциональном программировании оператор присваивания отсутствует, объекты нельзя изменять и уничтожать, можно только создавать новые путём
Каковы же преимущества чистых функциональных языков? Помимо упрощения анализа программ есть ещё одно
=== Отложенные вычисления ===
В традиционных языках программирования (например, [[w:C++|
Если функциональный язык не поддерживает отложенные вычисления, то он называется строгим. На самом деле, в таких языках порядок вычисления строго определён. В качестве примера строгих языков можно привести [[w:Scheme|Scheme]], [[w:Standard ML|Standard ML]] и [[w:CaML Light|CaML]]. Языки, использующие отложенные вычисления, называются нестрогими. [[w:Haskell|Haskell]] — нестрогий язык, так же как, например, Gofer и Miranda. Нестрогие языки зачастую являются чистыми.
Очень часто строгие языки включают в себя средства поддержки некоторых полезных возможностей, присущих нестрогим языкам, например бесконечных списков. В поставке [[w:Standard ML|Standard ML]] присутствует специальный модуль для поддержки отложенных вычислений. А [[w:OCaml|Objective Caml]] помимо этого поддерживает дополнительное
== Решаемые задачи ==
|