На практике отличие математической функции от понятия «функции» в императивном программировании заключается в том, что императивные - pismo.netnado.ru o_O
Главная
Поиск по ключевым словам:
страница 1
Похожие работы
На практике отличие математической функции от понятия «функции» в императивном программировании - страница №1/1

10 .

Функциона́льное программи́рование — раздел дискретной математики и парадигм программирования, в которой процесс вычисления трактуется как вычисление значений функций в математическом понимании последних (в отличие от функций как подпрограмм в процедурном программировании). Противопоставляется парадигме императивного программирования, которая описывает процесс вычислений как последовательность изменения состояний (в значении, подобном таковому в теории автоматов). Функциональное программирование не предполагает изменяемость данных (в отличие от императивного, где одной из базовых концепций является переменная).

На практике отличие математической функции от понятия «функции» в императивном программировании заключается в том, что императивные функции взаимодействуют и изменяют уже определенные данные. Таким образом, в императивном программировании, при вызове одной и тойже функции с одинаковыми параметрами можно получить разные данные на выходе, из за влияние на функцию внешних факторов. А в функциональном языке при вызове функции с одними и теми же аргументами мы всегда получим одинаковый результат в обоих случаях, входные данные не могут измениться, выходные данные зависят только от них.



λ-исчисления являются основой для функционального программирования, многие функциональные языки можно рассматривать как «надстройку» над ними[1].

Наиболее известными языками функционального программирования являются: Haskell — чистый функциональный. Назван в честь Хаскелла Карри.



  • LISP (Джон МакКарти, 1958, множество его потомков, наиболее современные из которых — Scheme и Common Lisp).

  • ML (Робин Милнер, 1979, из ныне используемых диалектов известны Standard ML и Objective CAML).

  • Miranda (Дэвид Тёрнер, 1985, который впоследствии дал развитие языку Haskell).

  • Erlang — (Joe Armstrong, 1986) функциональный язык с поддержкой процессов.

  • Nemerle — гибридный функционально/императивный язык.

Функциональное программирование в нефункциональных языках

Принципиально нет препятствий для написания программ в функциональном стиле на языках, которые традиционно не считаются функциональными (точно так же, как программы в объектном стиле можно писать на обычных структурных языках). Некоторые императивные языки поддерживают типичные для функциональных языков конструкции, такие как функции высшего порядка и дополнение списков (list comprehensions), что облегчает использование функционального стиля в этих языках



Особенности

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

Сильные стороны

Повышение надёжности кода

Привлекательная сторона вычислений без состояний — повышение надёжности кода за счет чёткой структуризации и отсутствия необходимости отслеживания побочных эффектов. Любая функция работает только с локальными данными и работает с ними всегда одинаково, независимо от того, где, как и при каких обстоятельствах она вызывается. Невозможность мутации данных при пользовании ими в разных местах программы исключает появление труднообнаруживаемых ошибок (таких, например, как случайное присваивание неверного значения глобальной переменной в императивной программе).

Удобство организации модульного тестирования

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

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



Возможности оптимизации при компиляции

Традиционно упоминаемой положительной особенностью функционального программирования является то, что оно позволяет описывать программу в так называемом «декларативном» виде, когда жесткая последовательность выполнения многих операций, необходимых для вычисления результата, в явном виде не задаётся, а формируется автоматически в процессе вычисления функций.[источник?] Это обстоятельство, а также отсутствие состояний даёт возможность применять к функциональным программам достаточно сложные методы автоматической оптимизации.

Возможности параллелизма

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

Недостатки

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



Для преодоления недостатков функциональных программ уже первые языки функционального программирования включали не только чисто функциональные средства, но и механизмы императивного программирования (присваивание, цикл, «неявный PROGN» были уже в LISPе). Использование таких средств позволяет решить некоторые практические проблемы, но это означает отход от идей (и преимуществ) функционального программирования и написание императивных программ на функциональных языках