Clojure:何时使用可变状态

Clojure:何时使用可变状态,clojure,Clojure,我在Clojure执行。到目前为止,我正在函数之间传递一个“世界状态”对象。它非常“实用”,我可以通过简单地向系统提供一个虚构的世界状态来模拟游戏的任何时刻 由于Clojure有一个非常复杂的管理状态(引用、原子…)的系统,我想知道什么是编程Clojure更惯用的方法,是使用它的系统还是坚持一种更实用的方法 谢谢 编辑: 这是一篇有趣的文章,我刚刚发现它或多或少描述了我正在使用的模式。以当前的功能风格编写游戏已经是正确的方法,只要只有一个线程或上下文正在写入该数据(这是重复出现时发生的情况)。实

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

由于Clojure有一个非常复杂的管理状态(引用、原子…)的系统,我想知道什么是编程Clojure更惯用的方法,是使用它的系统还是坚持一种更实用的方法

谢谢

编辑:


这是一篇有趣的文章,我刚刚发现它或多或少描述了我正在使用的模式。

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

纯函数已经是习惯的Clojure。引用类型(ref、atom、agent)用于协调共享状态

只要不共享任何内容(您不是在一个线程中更新世界,而在另一个线程中渲染,或者在自己的线程中协调多个玩家),就没有理由共享状态,因此也没有理由脱离纯功能风格


另一个例外是对性能进行优化:但是当性能可以通过可变性得到增强时,您希望尽可能地保持突变的局部性。这就是瞬态或Java数组的用武之地。包装这些可变优化的函数通常仍然是纯函数。

Clojure是一种函数式编程语言,旨在利用多核/SMP处理器。在没有共享内存访问的情况下,您可以从函数式编程语言中获得很多东西,Erlang确实做到了这一点,但它并没有利用所有处理器的能力

与“参与者模型”语言相比,clojure的亮点在于多个线程希望以有意义和协调的方式处理同一数据。如果您有一个简单的并行化问题,比如图像处理,那么您不需要这些优势,只需向每个工作人员发送一块数据即可。当这些数据位相互依赖时,协调共享访问就成为了真正的优势

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


除了速度,使用这种模型编辑游戏世界的另一个原因是允许你将做不同事情的进程分成不同的线程。在Rich早期的clojure示例中,他展示了一个蚂蚁模拟器,其中每个蚂蚁都有自己的线程来更新蚂蚁在棋盘上的位置,是的,这个程序非常简单且单线程:用户输入->解析->打印内容->用户输入…即使你有多个线程,坚持函数风格仍然是最好的方法-你希望尽可能拥有纯函数,并且仅在需要协调对共享游戏状态的访问时使用Clojure的可变引用(例如,使用atom或ref以便渲染线程可以看到最新的游戏世界状态)。其他一切都可以是纯粹的/不变的。