Функциональное программирование: состояние по сравнению с переназначением

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

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

основной цикл будет выглядеть так:

13
задан Kent Fredric 25 December 2008 в 02:04
поделиться

4 ответа

В чистом функциональном стиле Вы никогда не будете перезаписывать переменной.

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

Конечно, детали того, как связать последовательность значений к "объектным идентификационным данным", могут быть немного волосатыми. У Haskell есть Монады, которые позволяют Вам образцовое состояние. Функциональное Реактивное программирование является более литеральной попыткой моделирования объектов в мире с чистыми функциональными обновлениями, что я думаю, очень перспективное направление для программирования.

Я отмечу, что Clojure, в отличие от Haskell, не чист, и можно обновить переменные, как Вы предположили. Если Вы только обновите несколько переменных на высоком уровне, то Вы будете все еще, вероятно, пользоваться многими концептуальными преимуществами простоты функционального программирования.

11
ответ дан 1 December 2019 в 21:53
поделиться

Взгляд на Haskell, который является чистым функциональным языком — он не имеет никакого переназначения вообще, а также никаких других побочных эффектов: чтобы сделать, IO, в монаде IO создают, она на самом деле заменяет RealWorld новым экземпляром мира, который имеет, например, новый текст, отображенный в консоли.

1
ответ дан 1 December 2019 в 21:53
поделиться

По-видимому, в мире OO Вы имеете цикл и изменяете эти банковские счета много раз в ответ на запросы. Давайте предположим, что у Вас есть целый портфель учетных записей, и они имеют Портфель типа. Затем в Haskell Вы записали бы чистую функцию

updatePortfolio :: Request -> Portfolio -> Portfolio

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

readRequest :: IO Request  -- an action that, when performed, reads a Request with side effects

main :: Portfolio -> IO ()  -- a completely useless program that updates a Portfolio in response to a stream of Requests

main portfolio = do req <- readRequest
                    main (updatePortfolio req)

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

Это - очень игрушечный пример, но я надеюсь, что он дает Вам немного разновидности функционального языка.

8
ответ дан 1 December 2019 в 21:53
поделиться

Так..., что я делаю с ним? Перезапись любая переменная ссылалась на старый банковский счет?

Да

Если так, это имеет преимущества перед изменяющим состояние подходом ООП?

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

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

Кроме того, мы можем оставить свободное место при помощи данных из другой структуры, с которой мы копируем. Классический пример при добавлении элемента к заголовку списка. Если у нас есть указатель на второй элемент и указатель на первый элемент, мы можем сослаться на оба списка только с размером первого (см. ниже). Без неизменности мы не можем гарантировать это.

        b__
           |  
a -> [6|] -+-> [5|] -> [4|] -> [3|] -> [2|] -> [1|x]
4
ответ дан 1 December 2019 в 21:53
поделиться
Другие вопросы по тегам:

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