Clojure: когда использовать изменяемое состояние - PullRequest
12 голосов
/ 14 октября 2011

Я реализую небольшую "игровую" вещь в Clojure. Пока что я передаю объект «статус мира» среди функций. Он очень «функционален», и я могу имитировать любой момент игры, просто наполняя систему искусственным миром.

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

Спасибо.

EDIT:

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

Ответы [ 3 ]

13 голосов
/ 14 октября 2011

Чистые функции уже идиоматичны Clojure. Типы ссылок (ref, atom, agent) существуют для координации shared состояния.

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

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

6 голосов
/ 14 октября 2011

Clojure - это функциональный язык программирования, разработанный для использования преимуществ многоядерных / SMP-процессоров. Вы можете получить много от функционального языка программирования без доступа к общей памяти, и действительно, Erlang делает это замечательно, но он не использует все возможности процессора.

Где clojure сияет по сравнению с языками «модель актора», это когда несколько потоков хотят работать над одними и теми же данными осмысленным и скоординированным образом. Если у вас есть тривиально распараллеливаемая проблема, такая как обработка изображений, вам не нужны эти преимущества, и вы можете просто отправить один кусок данных каждому работнику. Когда эти биты данных взаимозависимы, то скоординированный совместный доступ становится реальным преимуществом.

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

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

4 голосов
/ 14 октября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...