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

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

Что такое функциональное программирование, почему и / xor, где я хочу использовать его вместо нефункционального программирования, и правильно ли я считаю, что C является нефункциональным языком программирования?

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

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

Haskell вместо этого использует другой подход к IO: monads. Это объекты, которые содержат требуемую операцию ввода-вывода, которая должна выполняться с помощью верхнего уровня вашего интерпретатора. На любом другом уровне они просто объекты в системе.

Какие преимущества дает функциональное программирование? Функциональное программирование позволяет кодировать с меньшим потенциалом для ошибок, поскольку каждый компонент полностью изолирован. Кроме того, использование функций рекурсии и первого classа позволяет использовать простые доказательства правильности, которые обычно отражают структуру кода.

Что такое функциональное программирование

Сегодня существуют два разных определения «функционального программирования»:

Предыдущее определение (исходящее из Lisp) заключается в том, что функциональное программирование связано с программированием с использованием первоclassных функций, то есть где функции обрабатываются как любое другое значение, поэтому вы можете передавать функции в качестве аргументов другим функциям, а функция может возвращать функции среди своих возвращаемых значений. Это приводит к использованию функций более высокого порядка, таких как map и reduce (вы, возможно, слышали о mapReduce как о единственной операции, которую Google использовал, и, что неудивительно, это близкий родственник!). Типы .NET System.Func и System.Action предоставляют функции более высокого порядка, доступные на C #. Хотя currying нецелесообразно в C #, функции, которые принимают другие функции в качестве аргументов, являются общими, например, функция Parallel.For .

Более молодое определение (популяризированное Haskell) заключается в том, что функциональное программирование также связано с минимизацией и контролем побочных эффектов, включая мутацию, то есть написание программ, которые решают проблемы путем составления выражений. Это чаще всего называют «чисто функциональным программированием». Это стало возможным благодаря совершенно различным подходам к структурам данных, называемым «чисто функциональными структурами данных». Одна из проблем заключается в том, что перевод традиционных императивных алгоритмов на использование чисто функциональных структур данных обычно делает производительность в 10 раз хуже. Haskell – единственный сохранившийся чисто функциональный язык программирования, но концепции проникли в основное программирование с такими библиотеками, как Linq на .NET.

где я хочу использовать его вместо нефункционального программирования

Везде. Lambdas в C # теперь продемонстрировали основные преимущества. C ++ 11 имеет lambda. Нет никакого оправдания, чтобы не использовать функции более высокого порядка. Если вы можете использовать такой язык, как F #, вы также сможете воспользоваться типом вывода, автоматическим обобщением, каррированием и частичным приложением (а также множеством других языковых функций!).

Правильно ли я полагаю, что C является нефункциональным языком программирования?

Да. C – процедурный язык. Тем не менее, вы можете получить некоторые преимущества функционального программирования, используя указатели функций и void * в C.

Возможно, стоит проверить эту статью на F # «101» на CoDe Mag, опубликованной недавно.

Кроме того, у Дастина Кэмпбелла есть отличный блог, где он опубликовал много статей о своих приключениях о том, как быстро встать с F # ..

Надеюсь, вы найдете их полезными 🙂

РЕДАКТИРОВАТЬ:

Кроме того, просто чтобы добавить, мое понимание функционального программирования состоит в том, что все это функция или параметры для функции, а не экземпляры / объекты с сохранением состояния. Но я могу ошибаться. F # – это то, за что я умираю, чтобы попасть, но просто не есть время! 🙂

Пример кода Джона Статистика не показывает функциональное программирование, потому что, когда вы выполняете функциональное программирование, ключ заключается в том, что код НЕ НАЗНАЧЕНИЯ ( record = thingConstructor(t) является назначением), и у него нет НИКАКИХ localMap.put(record) ( localMap.put(record) – это заявление с побочным эффектом). В результате этих двух ограничений все, что выполняет функция , полностью захватывается своими аргументами и возвращаемым значением. Переписывая код статистиков так, как он должен был бы выглядеть, если бы вы хотели эмулировать функциональный язык с помощью C ++:

 RT getOrCreate (const T thing, 
                   const Функция > thingConstructor, 
                   const Карта > localMap) {
     return localMap.contains (t)?
         localMap.get (t):
         localMap.put (т, thingConstructor (т));
 }

В результате правила отсутствия побочных эффектов каждый оператор является частью возвращаемого значения (следовательно, return приходит первым ), и каждый оператор является выражением. В языках, обеспечивающих функциональное программирование, подразумевается ключевое слово return , а оператор if ведет себя как оператор C ++ ?: .

Кроме того, все является неизменным, поэтому localMap.put должен создать новую копию localMap и вернуть его вместо изменения исходного localMap способом обычной C ++ или Java-программы. В зависимости от структуры localMap копия может повторно использовать указатели в оригинале, уменьшая объем данных, которые необходимо скопировать.

Некоторые из преимуществ функционального программирования include в себя тот факт, что функциональные программы короче, и легче модифицировать функциональную программу (потому что нет никаких скрытых глобальных эффектов, чтобы принимать во внимание), и легче получить программу прямо в первое место.

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

Более популярные функциональные языки имеют действительно строгие системы типов. В OCAML вы даже не можете смешивать математику с числами и с плавающей запятой или использовать одни и те же операторы (+ для добавления целых чисел, +. Для добавления float). Это может быть либо преимуществом, либо недостатком, в зависимости от того, насколько высоко вы оцениваете возможность проверки типа для обнаружения определенных типов ошибок.

Функциональные языки также имеют действительно большие среды выполнения. Haskell – исключение (исполняемые файлы GHC почти такие же маленькие, как и программы C, как во время компиляции, так и во время выполнения), но программы SML, Common Lisp и Scheme всегда требуют тонны памяти.

Да, вы правы, думая, что C – нефункциональный язык. C – процедурный язык.

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

 SomeKindOfRecord getOrCreate(T thing) { if(localMap.contains(t)) { return localMap.get(t); } SomeKindOfRecord record = new SomeKindOfRecord(t); localMap = localMap.put(t,record); return record; } 

Это происходит очень часто. Теперь, на функциональном языке, я мог бы написать

 RT getOrCreate(T thing, Function> thingConstructor, Map> localMap) { if(localMap.contains(t)) { return localMap.get(t); } RT record = thingConstructor(t); localMap = localMap.put(t,record); return record; } 

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

 getOrCreate = myLib.getOrCreate(*, SomeKindOfRecord.constructor(), localMap); 

(где * является своего рода «оставить этот параметр открытым» обозначением, которое является своего рода каррированием)

а затем локальная getOrCreate точно такая же, как и в случае, если бы я записал все это в одной строке без каких-либо зависимостей наследования.

Если вы ищете хороший текст на F #

Эксперт F # в соавторстве с доном Симе. Создатель F #. Он работал над дженериками в .NET специально, чтобы создать F #.

F # моделируется после OCaml, поэтому любой текст OCaml поможет вам изучить F #.

Я нахожу, что такое функциональное программирование? быть полезным

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

Предпочитают явно, when параметр

 public Program getProgramAt(TVGuide guide, int channel, Date when) { Schedule schedule = guide.getSchedule(channel); Program program = schedule.programAt(when); return program; } 

над

 public Program getCurrentProgram(TVGuide guide, int channel) { Schedule schedule = guide.getSchedule(channel); Program current = schedule.programAt(new Date()); return current; } 

Функциональный язык активно враждебен побочным эффектам. Побочные эффекты – сложность, а сложность – это ошибки, а ошибки – дьявол. Функциональный язык поможет вам проявить враждебность к побочным эффектам.

В информатике функциональное программирование – это парадигма программирования – стиль построения структуры и элементов компьютерных программ, который рассматривает вычисления как оценку математических функций и позволяет избежать зависания и изменяемых данных . Это декларативная парадигма программирования, что означает, что программирование выполняется с помощью выражений. В функциональном коде выходное значение функции зависит только от аргументов, которые вводятся в функцию, поэтому вызов функции f дважды с тем же значением для аргумента x будет давать один и тот же результат f (x) каждый раз . Устранение побочных эффектов, т. Е. Изменений состояния, не зависящих от входных функций, может значительно облегчить понимание и outlookирование поведения программы, что является одним из ключевых мотивов развития функционального программирования. подробнее см. в wiki . некоторые примеры функциональных программных языков похожи на scala, javascript … и т. д.

Давайте будем гением компьютера.