【问题标题】:How to implement 'state-driven' programs in a functional way?如何以功能性的方式实施“状态驱动”程序?
【发布时间】:2013-08-10 16:37:03
【问题描述】:

我打算用 Racket 语言编写一个电路模拟器。
为此,我必须以任何形式(在 Racket 的情况下为列表)保存整个电路的初始电气状态,并在函数中重复传递该值,直到电路状态进入给定时间。

但是这样会不会反复将数据传递给函数,在堆栈中长大并最终对程序的性能产生影响?
我听说在递归函数的情况下,在编译时代码首先扩展到递归完成的最后阶段,然后从最深嵌套的一个开始一次评估一个。
如果这同样适用于这种情况(不仅是我的,而且在任何包含状态机的程序中)我是否应该依赖该语言不情愿地提供的可变数据结构?

在阅读了一堆赞美 FP 的文章后,我也试图做出改变。回首那些经历这些案件的日子,我疯狂地喝着可变状态的库尔艾滋病,现在我感觉自己像个罪犯。
如果问题是另一个重复或类似问题,请给我一个链接,我会很高兴地接受它并关闭这个问题(或者我可以吗?)。

【问题讨论】:

  • 这些是实施细节。通常,因为递归是循环的唯一方式,所以函数式语言非常擅长,所以你不需要关心。
  • 您对解释单子的答案感兴趣吗?
  • 或者解释一下函数响应式编程?
  • 除此之外,您只需对所描述的确定性系统演化进行尾递归,或对非确定性系统演化进行深度优先探索的非尾递归。
  • @lukstafi 和 Ingo 感谢您的回复。在我的情况下,系统是确定性的,我认为我应该只用尾递归就可以很好地走上正轨 - 但基本上这是编译器所做的,所以除了调用函数之外我应该做更多的事情,对吧?

标签: functional-programming racket immutability


【解决方案1】:

如果您的模拟器的“主循环”允许tail call elimination,则“堆栈”不会无休止地增长。本质上没有必要为函数调用将参数“推送”到“堆栈”上;而是跳转到函数的开头,重复使用参数。

尝试在此处搜索 [racket] tail recursion[racket] tail call 以查找(或不)尾部位置的示例。

【讨论】:

  • 阅读更多内容后,我明白了您的意思。所以我需要的是正确的尾调用。
猜你喜欢
  • 2014-11-17
  • 2021-06-27
  • 2010-09-10
  • 2012-10-31
  • 2018-11-27
  • 1970-01-01
  • 2014-06-11
  • 1970-01-01
  • 2012-08-07
相关资源
最近更新 更多