Истинное понимание разницы между процедурным и функциональным
мне действительно трудно понять разницу между процедурные и функциональное парадигмы программирования.
вот первые два абзаца из Википедии о функциональное программирование:
в информатике, функциональный
программирование это парадигма программирования
это рассматривает вычисление как
оценка математических функций
и избегает состояния и изменяемых данных. Оно
подчеркивает применение
функции, в отличие от
императивный стиль программирования, который
подчеркивает изменения в состоянии.
Функциональное программирование имеет свои корни
в лямбда-исчислении формальная система
разработанный в 1930-х годах для исследования
определение функции, функция
применение и рекурсия. Много
функциональные языки программирования
быть рассмотренным как разработки на
лямбда-исчисление.
на практике, разница между
математическая функция и понятие
о "функции", используемой в императиве
программирования заключается в том, что необходимо
функции могут иметь побочные эффекты,
изменение значения состояния программы.
Из-за этого им не хватает ссылочной
прозрачность, т. е. тот же язык
выражение может привести к разным
значения в разное время в зависимости от
состояние выполняемой программы.
И наоборот, в функциональном коде
выходное значение функции зависит
только на аргументах, которые являются входными
функции, поэтому вызов функция
fдважды с одинаковым значением для
аргументxбудет производить то же самое
результатf(x)оба раза. Устранение
побочные эффекты могут сделать его гораздо проще
чтобы понять и предсказать поведение
программы, которая является одним из ключевых
мотивации для развития
функциональное программирование.
в пункте 2, где говорится
и наоборот, в функциональном коде выходное значение функции зависит только от аргументы, которые вводятся в функцию, поэтому вызов функции
fдважды с одинаковым значением аргументаxдаст тот же результатf(x)оба раза.
разве это не тот же самый случай для процедурного программирования?
что следует искать в процедурных vs функциональных, которые выделяются?
8 ответов:
Функциональное Программирование
функциональное программирование относится к способности рассматривать функции в качестве значений.
давайте рассмотрим аналогию с "обычных" значений. Мы можем взять два целых значения и объединить их с помощью
+оператор для получения нового целого числа. Или мы можем умножить целое число на число с плавающей запятой, чтобы получить число с плавающей запятой.в функциональном программировании, мы можем совместить 2 значения функции для произведения а новое значение функции с помощью операторов типа написать или лифт. Или мы можем объединить значение функции и значение данных для получения нового значения данных с помощью операторов, таких как карта или раза.
обратите внимание, что многие языки имеют функциональные возможности программирования-даже языки, которые обычно не считаются функциональными языками. Даже дедушка Фортран поддерживал значения функций, хотя и не предлагал многого в пути функции-Объединение операторов. Для того, чтобы язык назывался "функциональным", он должен охватывать функциональные возможности программирования в большой степени.
Процедурное Программирование
процедурное программирование относится к способности инкапсулировать общую последовательность инструкций в процедуру, так что эти инструкции могут быть вызваны из многих мест, не прибегая к копированию и вставке. Поскольку процедуры были очень ранним развитием в программировании, то возможность почти всегда связана со стилем программирования, требуемым машинным или ассемблерным языком программирования: стиль, который подчеркивает понятие мест хранения и инструкций, которые перемещают данные между этими местами.
контраст
эти два стиля на самом деле не противоположны-они просто отличаются друг от друга. Есть языки, которые полностью охватывают оба стиля (например, LISP). Следующий сценарий может дать смысл о некоторых различиях в двух стилях. Давайте напишем некоторый код для бессмысленного требования, где мы хотим определить, имеют ли все слова в списке нечетное число символов. Во-первых, процедурный стиль:
function allOdd(words) { var result = true; for (var i = 0; i < length(words); ++i) { var len = length(words[i]); if (!odd(len)) { result = false; break; } } return result; }Я приму это как данность, что этот пример понятен. Теперь, функциональный стиль:
function allOdd(words) { return apply(and, map(compose(odd, length), words)); }действуя изнутри, это определение делает следующие вещи:
compose(odd, length)сочетает в себеoddиlengthфункции для создания новой функции, которая определяет, является ли длина строки нечетная.map(..., words)вызывает эту новую функцию для каждого элемента вwords, в конечном итоге возвращая новый список булевых значений, каждый из которых указывает, имеет ли соответствующее слово нечетное число символов.apply(and, ...)применяет оператор " и " к результирующему списку, и - ing все булевы вместе, чтобы дать окончательный результат.вы можете из этих примеров видно, что процедурное программирование очень заинтересовано в перемещении значений в переменных и явном описании операций, необходимых для получения конечного результата. В отличие от этого, функциональный стиль подчеркивает сочетание функций, необходимых для преобразования исходного до конечного вывода.
в Примере также показаны типичные относительные размеры процедурного и функционального кода. Кроме того, он демонстрирует, что эксплуатационные характеристики процедурный код может быть легче увидеть, чем функциональный код. Рассмотрим: вычисляют ли функции длины всех слов в списке или каждый останавливается сразу после нахождения первого четного слова длины? С другой стороны, функциональный код позволяет высококачественной реализации выполнять довольно серьезную оптимизацию, поскольку он в первую очередь выражает намерение, а не явный алгоритм.
Более Дальнеишее Чтение
этот вопрос приходит много... см., например:
- в чем разница между процедурным и функциональным программированием?
- может кто-нибудь дать мне примеры функционального программирования против императива/процедурного программирования?
- ООП против функционального программирования против процедурного
премия Джона Бэкуса Тьюринга лекция излагает мотивации для функционального программирования в большом деталь:
можно ли освободить Программирование от стиля фон Неймана?
Я действительно не должен упоминать эту бумагу в настоящем контексте, потому что она становится довольно технической, довольно быстро. Я просто не мог устоять, потому что я думаю, что это действительно фундаментально.
дополнение
комментаторы отмечают, что популярные современные языки предлагают другие стили программирования сверх-процессуального и функциональная. Такие языки часто предлагают один или несколько из следующих стилей программирования:
- запрос (например, список понимания, язык-интегрированный запрос)
- поток данных (например, неявная итерация, массовые операции)
- объектно-ориентированные (например, инкапсулированные данные и методы)
- ориентированный на язык (например, синтаксис конкретного приложения, макросы)
см. комментарии ниже для примеров того, как псевдо-код примеры этот ответ может извлечь выгоду из некоторых объектов, доступных из этих других стилей. В частности, процедурный пример выиграет от применения практически любой конструкции более высокого уровня.
представленные примеры намеренно избегают смешивания в этих других стилях программирования, чтобы подчеркнуть различие между двумя обсуждаемыми стилями.
реальное различие между функциональным и императивным программированием заключается в мышлении-императивные программисты думают о переменных и блоках памяти, в то время как функциональные программисты думают: "как я могу transform мои входные данные в мои выходные данные "- ваша "программа" - это конвейер и набор преобразований на данные чтобы взять его с входа на выход. Это интересная часть IMO, а не "ты не должен использовать переменные" немного.
как следствие этого мышления, программы FP обычно описывают что произойдет, а не конкретный механизм как это произойдет-это мощно, потому что если мы можем четко указать, что означает "Select" и "Where" и "Aggregate", мы можем свободно менять их реализации, так же, как мы делаем с AsParallel (), и вдруг наше однопоточное приложение масштабируется до n ядер.
Isn't that the same exact case for procedural programming?нет, потому что процедурный код может иметь побочные эффекты. Например, он может хранить состояние между вызовами.
тем не менее, можно написать код, который удовлетворяет этому ограничению в языках, считающихся процедурными. И также можно написать код, который нарушает это ограничение в некоторых языках, считаются функциональными.
Я не согласен с ответом WReach. Давайте немного деконструируем его ответ, чтобы увидеть, откуда берется несогласие.
во-первых, его код:
function allOdd(words) { var result = true; for (var i = 0; i < length(words); ++i) { var len = length(words[i]); if (!odd(len)) { result = false; break; } } return result; }и
function allOdd(words) { return apply(and, map(compose(odd, length), words)); }первое, что следует отметить, что он сливается:
- функциональное
- выражение ориентированного и
- итератор ориентированных
программирование и отсутствие возможности для итеративного программирования стиля иметь больше явный поток управления, чем типичный функциональный стиль.
давайте быстро поговорим об этих.
выражение-ориентированный стиль, когда вещи, как можно больше, оценить к вещам. Хотя функциональные языки известны своей любовью к выражениям, на самом деле возможно иметь функциональный язык без составных выражений. Я собираюсь сделать один, где есть нет выражения, просто заявления.
lengths: map words length each_odd: map lengths odd all_odd: reduce each_odd andэто почти то же самое, что и раньше, за исключением того, что функции связаны исключительно через цепочки операторов и привязок.
итератор-ориентированный стиль программирования может быть взят Python. Давайте использовать чисто итеративный, итератор-ориентированный стиль:
def all_odd(words): lengths = (len(word) for word in words) each_odd = (odd(length) for length in lengths) return all(each_odd)это не функционально, потому что каждое предложение является итерационным процессом, и они связаны между собой явной паузой и возобновлением стека кадры. Синтаксис может быть частично вдохновлен функциональным языком, но он применяется к полностью итеративному его воплощению.
конечно, вы можете сжать это:
def all_odd(words): return all(odd(len(word)) for word in words)необходимо не так уж плохо, а? :)
последний пункт был о более явном потоке управления. Давайте перепишем исходный код, чтобы использовать этот:
function allOdd(words) { for (var i = 0; i < length(words); ++i) { if (!odd(length(words[i]))) { return false; } } return true; }С помощью итераторов можно:
function allOdd(words) { for (word : words) { if (!odd(length(word))) { return false; } } return true; }
Ну и что и точка функционального языка, если разница между:
return all(odd(len(word)) for word in words)return apply(and, map(compose(odd, length), words))for (word : words) { if (!odd(length(word))) { return false; } } return true;
основной отличительной особенностью функционального языка программирования является то, что он удаляет мутации как часть типичной модели программирования. Люди часто принимают это за то, что функциональный язык программирования не имеет операторов или использует выражения, но это упрощение. Функциональный язык заменяет явный вычисление с объявлением поведения, которое затем язык выполняет сокращение.
ограничение себя этим подмножеством функций позволяет вам иметь больше гарантий о поведении ваших программ, и это позволяет вам составлять их более свободно.
когда у вас есть функциональный язык, создание новых функций, как правило, так же просто, как составление тесно связанных функций.
all = partial(apply, and)это не просто, а может быть даже и нет возможно, если вы явно не контролировали глобальные зависимости функции. Лучшая особенность функционального программирования заключается в том, что вы можете последовательно создавать более общие абстракции и доверять тому, что они могут быть объединены в большее целое.
в процедурной парадигме (вместо этого я должен сказать "структурированное Программирование"?), у вас есть общая изменяемая память и инструкции, которые читают/записывают ее в некоторой последовательности (один за другим).
в функциональной парадигме, у вас есть переменные и функции (в математическом смысле: переменные не меняются с течением времени, функции могут вычислять только то, на основе их предложений).
(Это упрощено, например, FPLs обычно имеют средства для работы с изменяемой памятью в то время как процедурные языки часто могут поддерживать процедуры более высокого порядка, поэтому все не так ясно; но это должно дать вам представление)
The очаровательный Python: функциональное программирование в Python С IBM Developerworks действительно помог мне понять разницу.
особенно для тех, кто немного знает Python, примеры кода в этой статье, в которых сравниваются различные вещи функционально и процедурно, могут прояснить разницу между процедурным и функциональным программированием.
в функциональном программировании для того, чтобы рассуждать о значении символа (переменной или имени функции) вам действительно нужно знать только 2 вещи-текущую область и имя символа. Если у вас есть чисто функциональный язык с неизменяемостью, оба они являются "статическими" (извините за сильно перегруженное имя) понятиями, что означает, что вы можете видеть как текущую область, так и имя, просто взглянув на исходный код.
в процедурном программировании, если вы хотите ответить на вопрос в том, что значение за
xвы также должны знать, как вы туда попали, область и имя сами по себе не достаточно. И это то, что я считаю самой большой проблемой, потому что этот путь выполнения является свойством "runtime" и может зависеть от стольких разных вещей, что большинство людей учатся просто отлаживать его, а не пытаться восстановить путь выполнения.
Я недавно думал о разнице в терминах Проблема Выражения. описание Фила Уодлера часто цитируется, но принятый ответ на этот вопрос вероятно, легче следовать. В принципе, кажется, что императивные языки склонны выбирать один подход к проблеме, в то время как функциональные языки склонны выбирать другой.
Comments