函数式编程如何应用于模拟?

20
除了标题中提到的一般性问题外,
  • 函数式编程者和函数式语言如何处理仿真领域,这似乎最自然的方法是使用面向对象语言?
  • 有哪些开源的复杂仿真示例是以(基本上)函数式风格编写的?
  • 面向对象编程者需要哪些视角变化,才能从函数式范式开始处理仿真?

当学习Clojure的创始人Rich Hickey如何专注于解决OO编程和可变状态的"附带复杂度"时,我提出了这个问题。例如,Clojure将标识和状态分离是有意义的(Hickey的ants.clj在学习列表中)。另一个相关领域是使用函数式编程进行游戏开发,而游戏往往是具有大量状态性“事物”的仿真;已经有一些关于FP和游戏的文章/论文,但更多的是可以欢迎的。

也许有经验的函数式编程者可以提供额外的背景和建议,以便以函数式风格特别是用于仿真方面重新定位思维。先感谢您的回答!


感谢大家迄今为止提供的有用回复。似乎还没有一个“规范”的参考来说明如何从面向对象范式模拟过渡到函数式范式模拟,但是在阅读所有分享的链接和代码时,也许我会冒险自己撰写一篇。 :) - limist
1
我几年前问过一个类似的问题,下面包含了一个链接,因为有一些好的答案,可能对其他对这个话题感兴趣的人有所帮助。https://dev59.com/FnRB5IYBdhLWcg3wF0LH - Frank Henard
@Ballpark - 感谢你的链接,我早先就看到了你的问题,并从中学到了东西。 - limist
6个回答

6

Michal的答案很好,但我想再加上一些我个人发现有用/有趣的例子。

第一个是Lau Jenson关于functional fluid dynamics的帖子(和代码)。虽然他在这里确实采用了可变路线以提高速度,但风格相当功能性。我敢打赌,在Clojure 1.3中,这可以(大部分!)不可变地完成,并具有合理的性能。

下一个是用Clojure实现的simple Snake game。阅读起来很容易,尽管需要花费大约一个小时左右,但风格非常愉悦和协调。

此外,一些值得一看的代码(我认为!)是用于建模神经网络的代码。Jeff Foster有一些单层感知器代码,以及一些更惯用的代码修订。即使您不熟悉NNs,也值得一看。他还有一些关于流体动力学的最新帖子,不过这次是用Haskell编写的。(第I部分第II部分)我认为也很有趣的是他的生命游戏实现(& 第II部分)。

最后,正如Michal在我之前提到的,Brian Carper正在开发使用Clojure的角色扮演游戏。他最近发布了一些游戏艺术作品,所以我敢打赌这个游戏仍在开发中;)

我喜欢使用序列库来处理大量数据;使用像mapreduce这样的抽象和有趣、方便的工具,如juxt,感觉更自然,而不是简单的命令式迭代。但我发现,使用Clojure/函数式语言重新实现已知和已实现的命令式算法确实需要付出一定的代价。

玩得开心!


4

我不确定自己有能力撰写一份关于问题所提出的全面分析,但至少我可以发布一些FP与游戏方面的有趣链接:

Jörg W. Mittag在这个答案中提供了许多有趣的例子,回答了一个关于“现实世界”Haskell编程的问题(其中包含一些有趣的文章链接——纯函数式复古游戏系列真的值得一读)。

在Clojure领域,Phil Hagelberg为他的Clojure编程PeepCode演示实现了一个基于文本的冒险游戏; 代码可在GitHub上找到。然后是Brian Carper的RPG项目; 尽管过去有一篇文章看起来非常酷,但没有公开发布任何代码(因此让我们一起向Brian施加压力以继续开发;-))。最后,这里有一个使用Penumbra的简单游戏示例(由于某些原因--可能与Clojure无关--我无法使其正常工作,但您可以尝试一下,并且还附有说明)。

对于模拟,研究ants.clj是一个好主意。此外,我记得在某个地方(90%可能是他们的YouTube频道)看到了一系列基于SICP的UC Berkeley(我想是这个学校...?)入门编程课程讲座; 他们有三节关于Scheme中面向对象编程的讲座,我认为他们提到模拟作为提供良好用例的领域。请注意,我对这个记忆非常模糊,所以很难说它对你有多大用处。


非常好的回答!虽然Mire很有趣,而Peepcode 呈现也是一个很好的复习方式(我太晚才看到,没能获得它所具有的美妙介绍价值)。此外,布莱恩显然仍在开发RPG游戏。让我们期待一下吧! - Isaac
Michal,感谢您提供的有用链接和信息。关于基于SICP的面向对象编程讲座,也许您是指这里的第16-18讲?http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/lecture-notes/ - limist
@limist:不,我指的是加州大学伯克利分校SICP课程的第17-19讲 -- 刚刚重新发现了链接:http://www.youtube.com/ucberkeley#g/c/6879A8466C44A5D5 @Isaac Hodes:谢谢!也很高兴知道Brian还在继续。感谢您分享的酷链接。 :-) - Michał Marczyk

4
我正在使用Clojure编写游戏,采用大部分函数式风格。例如,整个游戏状态被建模为一个不可变的数据结构。
这需要一些略微复杂的编码。例如,您经常需要创建具有许多参数的函数来传递各种游戏状态元素,并确保应用游戏状态更新到最新的游戏版本。
但它也带来了一些非常好的优势,例如并发证明相当简单,您可以做一些有趣的事情,比如克隆整个游戏状态以在AI中运行不同的模拟。
总的来说,我很高兴Clojure成为模拟/游戏语言。
基于这种经验,我认为会改善Clojure的游戏/模拟的东西是:
- 更好地支持原语,特别是作为函数参数和返回值 - 实现核心语言函数,减少对内存分配的压力(GC压力对交互式游戏是一个问题!)
您可以在这里看到游戏的早期版本:Ironclad - Generals of Steam。它基本上是一个蒸汽朋克主题的策略游戏。

3

最近,Uncle Bob开始涉足Clojure,特别是开发了一个轨道模拟器,成为他公开的示例。

以下是相关链接:


3

2
模拟是一种解释器 -- 它们易于以函数式风格编写。它们也可以被设计为self-optimizing simulators,基于将它们视为编译器。

1
谢谢,请问您能否分享更多关于“解释器形式”的模拟的例子/参考资料?我对非面向对象编程风格还比较陌生,刚开始逐渐摆脱这种思维方式。我想最终为我正在开发的模拟编写DSL,所以任何在这方向上的额外指导都将不胜感激,谢谢。 - limist
1
您链接的文件目前无法公开访问。 - Preza8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接