【问题标题】:How does functional programming apply to simulations?函数式编程如何应用于仿真?
【发布时间】:2011-03-26 18:57:23
【问题描述】:

除了标题中的一般问题,

  • 函数式程序员和函数式语言如何处理模拟领域,而这似乎最自然地由面向对象的语言处理?
  • 是否有以(大部分)函数式编写的复杂模拟的开源示例?
  • OO 程序员需要改变哪些视角,才能从功能范式进行模拟?

我在学习 Clojure 的创建者 Rich Hickey 如何专门寻求驯服 OO 编程和可变状态的“偶然复杂性”时提出这个问题,例如Clojure 的身份和状态分离很有意义(Hickey 的 ants.clj 在研究列表中)。另一个相关领域是在游戏中使用函数式编程,这通常是到处都有大量有状态的“事物”的模拟;有一些关于FP和游戏的文章/论文,欢迎更多。

也许经验丰富的函数式程序员可以提供额外的背景知识和建议,说明如何将自己的思维重新定位为函数式风格,特别是针对模拟。提前致谢!

【问题讨论】:

  • 谢谢大家,到目前为止您的有用回复。似乎还没有关于如何从 OO 范式模拟过渡到功能范式模拟的“规范”参考,但是在阅读所有共享的链接和代码时,也许我会冒险自己写出来。 :)
  • 几年前我问了一个类似的问题,我在下面提供了一个链接,因为有一些很好的答案,可能对其他对此主题感兴趣的人有所帮助。 stackoverflow.com/questions/718935/…
  • @Ballpark - 感谢您的链接,我之前已经看到您的问题并从中吸取了教训。

标签: functional-programming clojure simulation


【解决方案1】:

我不确定我是否能够应对挑战,对问题中提出的问题进行全面分析,但我至少可以在 FP 与游戏方面发布一些有趣的链接:

Jörg W. Mittag 在this answer 中为有关“真实世界”Haskell 编程的问题提供了许多有趣的示例(附有一些有趣文章的链接——Purely Functional Retrogames 系列确实值得一读)。

在 Clojure 领域,Phil Hagelberg 为他的 PeepCode Clojure 编程截屏实现了一个基于文本的冒险游戏;代码可用on GitHub。然后是 Brian Carper 的RPG project;还没有公开发布的代码,只有前段时间的一篇帖子(不过看起来很酷,所以让我们一起向 Brian 施压;-))。最后,here 是一个使用 Penumbra 的简单游戏的示例(出于某种原因——可能与 Clojure 无关——我无法让它工作,但你可能会,而且附上一篇文章)。

至于模拟,学习ants.clj 是个好主意。另外,我记得在加州大学伯克利分校的一门编程入门课程中看到了一系列基于 SICP 的讲座(我认为......?)在某个地方可以找到(90% 是在他们的 YouTube 频道上);他们在 Scheme 中进行了三场关于 OOP 的讲座,我认为他们提到模拟是一个为该方法提供良好用例的领域。请注意,我对这个记忆很模糊,所以我很难说它对你有多大用处。

【讨论】:

  • 优秀的答案!不过 Mire 读起来很有趣,而 Peepcode 演员表是回顾事物的好方法(可惜我看得太晚了,无法获得它具有的不错的介绍价值)。另外,Brian 显然还在为 RPG 工作。兴奋起来。
  • Michal,感谢您提供有用的链接和信息。回覆。基于 SICP 的 OOP 讲座,也许你的意思是 Lectures 16-18 这里? ocw.mit.edu/courses/electrical-engineering-and-computer-science/…
  • @limist:不,我指的是加州大学伯克利分校 SICP 课程的第 17-19 课——刚刚重新发现了链接:youtube.com/ucberkeley#g/c/6879A8466C44A5D5@Isaac Hodes:谢谢!另外,很高兴知道布赖恩还在。并感谢您自己收集的很酷的链接。 :-)
【解决方案2】:

Michal 的回答非常好,但我想我会添加一些我个人认为有用/有趣的其他简洁示例。

第一个是 Lau Jenson 关于functional fluid dynamics 的帖子(和代码)。虽然他在这里肯定会走可变的速度路线,但这种风格相当实用。我敢打赌 Clojure 1.3 这可以(大部分!)以合理的性能不变地完成。

接下来是在 Clojure 中实现的 simple Snake game。一个小时左右就可以轻松阅读,而且风格非常愉快和有凝聚力。

此外,一些简洁的代码(我认为!)是代码建模神经网络。 Jeff Foster 有一些 single layer 感知器代码,还有一些 idiomatic revisions of the code。值得一看,即使您不熟悉 NN。他最近也有一些关于流体动力学的帖子,不过这次是在 Haskell。 (Part IPart II) 我认为他的 implementation of the Game of Life (& Part II) 也很有趣。

最后,正如 Michal 在我之前提到的,Brian Carper 正在开发 a RPG in Clojure。他recently posted some artwork 负责游戏,所以我打赌它仍在开发中;)

我喜欢使用序列库来处理大量数据;使用mapreduce 之类的抽象,以及juxt 之类的有趣、方便的工具,而不是简单的命令式迭代,感觉更自然。我发现,通过使用 Clojure/函数式语言来重新实现众所周知且实现良好的命令式算法,你确实要纳税。

玩得开心!

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 谢谢,您能否分享更多关于模拟作为“解释器形式”的示例/参考?我对非面向对象的编程风格相当陌生,并且刚刚开始摆脱这种思维模式。我确实想最终为我正在研究的模拟编写一个 DSL,所以任何在这个方向上的额外指针都将不胜感激,谢谢。
    • 您链接的文件不能公开访问(现在)。
    【解决方案4】:

    Bob 大叔最近一直在玩 Clojure,特别是编写一个轨道模拟器作为他最公开的例子。

    一些链接:

    【讨论】:

      【解决方案5】:

      我正在用 Clojure 编写游戏,主要使用的是函数式风格。例如,整个游戏状态被建模为一个不可变的数据结构。

      这需要一些稍微复杂的编码。例如,您经常会创建带有大量参数的函数来传递游戏状态的各种元素,并确保将游戏状态更新应用到最新的游戏版本。

      但它也带来了一些非常好的优势,例如并发性已被证明是微不足道的,您可以做一些有趣的事情,例如克隆整个游戏状态以在 AI 中运行不同的模拟。

      总的来说,我很高兴 Clojure 作为一种用于模拟/游戏的语言。

      根据这次经验,我认为可以改进 Clojure 的游戏/模拟功能是:

      • 更好地支持原语,尤其是作为函数参数和返回值
      • 实现对内存分配不那么困难的核心语言函数(GC 压力是交互式游戏的一个问题!)

      您可以在此处查看游戏的早期版本:Ironclad - Generals of Steam。它基本上是一个蒸汽朋克主题的策略游戏。

      【讨论】:

        【解决方案6】:

        为了补充其他答案:有一个名为功能响应式编程的学科,它解决了随时间变化并对外部事件做出反应的系统的功能表示问题。见

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-26
          • 2014-09-01
          • 2018-11-21
          • 2013-03-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多