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

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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

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

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

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

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

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

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

Ответ 3

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

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

Надеюсь, вы сочтете это полезным:)

EDIT:

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

Ответ 4

Код примера John the Statistician не показывает функциональное программирование, потому что, когда вы выполняете функциональное программирование, ключ состоит в том, что код НЕ НАЗНАЧЕН (record = thingConstructor(t) является назначением), и у него нет НИКАКИХ ПОБОЧНЫХ ЭФФЕКТОВ (localMap.put(record) - утверждение с побочным эффектом). В результате этих двух ограничений все, что выполняет функция function, полностью захватывается своими аргументами и возвращаемым значением. Переписывая статистический код так, как он должен был бы выглядеть, если бы вы хотели эмулировать функциональный язык с помощью С++:

RT getOrCreate(const T thing, 
                  const Function<RT<T>> thingConstructor, 
                  const Map<T,RT<T>> localMap) {
    return localMap.contains(t) ?
        localMap.get(t) :
        localMap.put(t,thingConstructor(t));
}

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

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

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

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

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

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

Ответ 5

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

Ответ 6

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

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

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

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

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

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

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

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

Ответ 7

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

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

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

Ответ 8

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

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

Предпочитает явный 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;
}

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

Ответ 9

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