这是一个理论问题,但是经过多年的编程之后,我意识到现在是“正常的”命令式技术,主要使用C ++,我发现了函数式编程的另一个领域,在偶然学习JavaScript时偶然发现了这个问题。
这使我想知道您是否可以用一个纯粹的功能且没有状态的不同实现在技术上替换任何完整的面向状态的程序?
这是一个有趣的想法,我必须承认,函数编程的清晰性和优雅性确实让我大吃一惊。
这是一个理论问题,但是经过多年的编程之后,我意识到现在是“正常的”命令式技术,主要使用C ++,我发现了函数式编程的另一个领域,在偶然学习JavaScript时偶然发现了这个问题。
这使我想知道您是否可以用一个纯粹的功能且没有状态的不同实现在技术上替换任何完整的面向状态的程序?
这是一个有趣的想法,我必须承认,函数编程的清晰性和优雅性确实让我大吃一惊。
Answers:
简短的回答:是的。根据维基百科,艾伦·图灵(Alan Turing)于1937年证明了λ演算与图灵机作为计算的通用模型的等效性。在谈论命令式或有状态编程时,通常会想到图灵机的计算模型,而lambda演算是“纯函数式编程”的数学形式化。
据推测,每个有效的计算模型都能够执行与图灵机相同的计算,反之亦然。这就是所谓的“ 教堂-图灵论题”。但是,由于或多或少的直觉性术语“有效的计算模型”(也许有人将来会发明新的模型?),因此无法证明这一推测。
在任何动态系统中,“状态”都是使您的现在受到过去或未来的影响的因素(时间的箭头不是数学问题,只是物理约束)。
无论您有“要记住”的东西还是取决于您所做的事情,您都有状态。
没有状态的系统不是“动态的”:它只是组合功能。那可能没有状态,但是-为了产生不同的结果-需要以某种方式提供状态。
现在,根据您引用的计算模型,状态可以显式(以变量的形式)或隐式(以“返回地址”的形式)表示。
当您执行操作时,您fna(fnb(x))
将给fnb一个状态,这反过来又会为fna产生一个状态。这是由于x
存在一个事实,即在调用fnb之前就已经存在(因此,它来自它自己的“过去”)。
这与“状态退出”或“状态不存在”无关。这是“我在乎”或“我不在乎”的问题。
只要您不必与外界交互,就可以避免显式的可变状态。
在JavaScript中,为了使您的程序真正发挥作用而不占用处理器周期,您必须修改Dom或Window对象,并且这些API是有状态的。但是我想您可以创建一个包装器,该包装器将Dom和Window对象作为参数传递给JavaScript代码,然后接收一个新的Dom / Window作为输出。这样可以将JavaScript代码与可变状态隔离开。
当然,您仍然依赖状态,因为浏览器窗口和DOM本质上是有状态的。任何交互式应用程序本质上都是有状态的,但是您仍然可以以最小化显式状态的方式构造代码。
一个不同的问题是这是否是一个好主意。甚至Haskell(按设计是一种纯粹的功能语言)也包含“状态”单子,该单子使您可以模拟可变状态。这表明明确的可变状态有时确实是一种理想的模式。