Преимущества программирования не сохраняющего состояние?

Используйте аналитику count:

select name, trip_id,
       count(*) over() as cnt
  from main 
 order by name
;
127
задан Sasha Chedygov 27 May 2012 в 21:10
поделиться

7 ответов

Прочтите Функциональное программирование в двух словах .

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

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

162
ответ дан 24 November 2019 в 00:45
поделиться

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

Вы можете найдите хорошее руководство с множеством примеров в статье Джона Хьюза Почему функциональное программирование имеет значение (PDF).

Вы будете на кучу более продуктивными, особенно если вы выберете функциональный язык, который также имеет алгебраические типы данных и сопоставление с образцом (Caml, SML, Haskell).

44
ответ дан 24 November 2019 в 00:45
поделиться

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

6
ответ дан 24 November 2019 в 00:45
поделиться

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

На самом деле я нахожу (из личного опыта), что программирование на F # соответствует тому, как я думаю лучше , а так проще. Я думаю, это самая большая разница. Я программировал как на F #, так и на C #, и в F # гораздо меньше «борьбы с языком», что мне нравится. Вам не нужно думать о деталях в F #. Вот несколько примеров того, что мне действительно нравится.

Например, несмотря на то, что F # статически типизирован (все типы разрешаются во время компиляции), вывод типа определяет, какие типы у вас есть, поэтому вам не нужно это говорить. И если он не может этого понять, он автоматически делает вашу функцию / класс / все что угодно универсальным. Так что вам никогда не придется писать что-то общее, все происходит автоматически. Я считаю, что это означает, что я трачу больше времени на размышления о проблеме и меньше на то, как ее реализовать. Фактически, всякий раз, когда я возвращаюсь к C #, я обнаруживаю, что очень скучаю по этому выводу типа, вы никогда не поймете, насколько это отвлекает, пока вам больше не нужно это делать.

Также в F # вместо написания циклов вы функции вызова. Это небольшое изменение, но существенное, потому что вам больше не нужно думать о конструкции цикла. Например, вот фрагмент кода, который может пройти и что-то сопоставить (не могу вспомнить, что именно, это из головоломки Эйлера проекта):

let matchingFactors =
    factors
    |> Seq.filter (fun x -> largestPalindrome % x = 0)
    |> Seq.map (fun x -> (x, largestPalindrome / x))

Я понимаю, что сделать фильтр, а затем карту (то есть преобразование каждого элемента) в C # было бы довольно просто, но вы должны думать на более низком уровне. В частности, вам нужно будет написать сам цикл и иметь свой собственный явный оператор if и тому подобное. С тех пор, как я изучил F #, я понял, что мне легче кодировать функциональным способом, где, если вы хотите фильтровать, вы пишете «filter», а если вы хотите сопоставить, вы пишете «map» вместо реализации каждая из деталей.

Мне также нравится оператор |>, который, как мне кажется, отделяет F # от ocaml и, возможно, других функциональных языков. Это оператор конвейера, он позволяет вам «перенаправить» вывод одного выражения на ввод другого выражения. Это заставляет код больше следовать тому, как я думаю. Как и в приведенном выше фрагменте кода, это ' говорит: «Возьмите последовательность факторов, отфильтруйте ее, затем сопоставьте». Это очень высокий уровень мышления, которого нельзя достичь в императивных языках программирования, потому что вы так заняты написанием операторов цикла и if. Это единственное, чего мне больше всего не хватает, когда я перехожу на другой язык.

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

Изменить : Я видел в одном из комментариев, который вы просили привести пример «состояния». "на функциональном языке программирования. F # можно написать императивно, поэтому вот прямой пример того, как можно иметь изменяемое состояние в F #:

let mutable x = 5
for i in 1..10 do
    x <- x + i
20
ответ дан 24 November 2019 в 00:45
поделиться

Обдумайте все сложные ошибки, на отладку которых вы потратили много времени.

Итак, сколько из этих ошибок произошло из-за «непреднамеренного взаимодействия» между двумя отдельными компонентами программы? (Почти все ошибки потоковой передачи имеют такую ​​форму: гонки, связанные с записью общих данных, взаимоблокировки, ... Кроме того, часто встречаются библиотеки, которые оказывают неожиданное влияние на глобальное состояние или читают / записывают реестр / среду и т. Д.) Я полагаю, что по крайней мере 1 из 3 «серьезных ошибок» попадает в эта категория.

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

Это большая победа от «неизменяемости» IMO. В идеальном мире мы все разрабатывали бы потрясающие API, и даже когда все было изменчиво, эффекты будут локальными и хорошо задокументированными, а «неожиданные» взаимодействия будут сведены к минимуму. В реальном мире существует множество API-интерфейсов, которые различными способами взаимодействуют с глобальным состоянием, и они являются источником самых пагубных ошибок. Стремление к безгражданству означает стремление избавиться от непреднамеренных / неявных / закулисных взаимодействий между компонентами.

15
ответ дан 24 November 2019 в 00:45
поделиться

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

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

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

8
ответ дан 24 November 2019 в 00:45
поделиться

Я написал сообщение только на эту тему некоторое время назад: О важности чистоты .

5
ответ дан 24 November 2019 в 00:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: