Clojure:何时使用可变状态

时间:2011-10-14 12:43:26

标签: clojure

我正在Clojure中实现a litte "game" thing 。到目前为止,我正在传递函数中的“世界状态”对象。它非常“实用”,我可以通过简单地为系统提供一个虚构的世界状态来模拟游戏的任何时刻

由于Clojure有一个非常复杂的系统来管理状态(参考,原子......),我想知道什么是编程Clojure更惯用的方式,无论是使用它的系统还是坚持更实用的方法。 / p>

感谢。

修改

This是一个有趣的读物,我刚刚发现它或多或少地描述了我正在使用的模式。

3 个答案:

答案 0 :(得分:13)

纯粹的功能已经是惯用的Clojure。引用类型(ref,atom,agent)用于协调共享状态。

只要没有共享(你在一个线程中更新世界而在另一个线程中渲染,或者在自己的线程上协调多个玩家),就没有理由分享状态,因此没有理由从纯粹中断功能风格。

另一个例外是优化性能:但是当可变性增强性能时,您希望将突变保持为尽可能本地化。这就是瞬态或Java数组的用武之地。包含这些可变优化的函数通常仍然是纯函数。

答案 1 :(得分:6)

Clojure是一种功能性编程语言,旨在利用多核/ SMP处理器。你可以在没有共享内存访问的情况下从函数式编程语言中获得很多东西,事实上Erlang做得非常好,但它并没有利用所有的处理器能力。

与'演员模型'语言相比,clojure闪耀的地方是多个线程想要以有意义和协调的方式处理相同的数据。如果您有像图像处理这样的平凡可并行化的问题,那么您不需要这些优势,您只需向每个工作人员发送一块数据。当这些数据位相互依赖时,协调共享访问成为真正的优势。

在游戏的上下文中,你可以使用它来让许多线程更新游戏世界,并将一个线程显示给用户。 a ref将确保用户始终看到一致的游戏世界,而许多线程正在编辑它。如果没有这个,你需要让每个线程负责确定何时向其显示用户,或只有线程。

使用这样一个模型来编辑游戏世界的另一个原因是,除了速度之外,允许你在Rich的早期clojure示例之一中将不同内容的进程分成不同的线程一个蚂蚁模拟器,其中每个蚂蚁都有自己的线程,更新了板上的蚂蚁位置,这使得一些非常简短的代码。

答案 2 :(得分:4)

以当前功能样式编写游戏已经是正确的方法,只要只有一个线程或上下文写入该数据(这是您重复时会发生的事情)。实际上,您提到的那些设施的关键优势是处理共享状态时。如果要使用多线程并行化程序,那么利用这些工具可能会很有用。