F#邮箱处理器与功能设计



如果状态被认为是函数的坏主意,为什么在使用MailboxProcessor时它被认为是可以的?

为了扩展,我向某人解释了函数编程,函数如何不使用状态(函数外没有变量,即相同的数据输出,相同的数据输入),以及这带来的好处。但后来我想到了MailboxProcessor,以及它使用递归在函数调用之间保持状态的方式,我无法完全理解为什么在这种情况下它是可以的。

这是否是一种保持状态的最不坏的方式?

真正的邪恶是共享可变状态。在单线程的情况下,共享可变状态意味着无法安全地组合函数,因为一个调用可以修改某个状态,然后由第二个调用读取,因此会得到意外的结果。在多线程的情况下,共享可变状态意味着您有可能出现竞争条件。

函数式编程通常避免突变。函数仍然可以共享某些状态(例如,闭包可以捕获一个状态),但它不能变异。在单线程的情况下,也不存在非确定性。在多线程的情况下,在纯函数风格中,几乎唯一可以做的事情就是进行fork-join并行(和数据并行),它不需要可变状态,并且是完全确定的。

基于代理的编程也避免了共享可变状态,但方式不同。您拥有的隔离代理只能共享不可变的消息。因此存在一些非确定性(因为它们通过发送消息进行通信),但它们只交换不可变的值。事实上,您甚至可以在代理内部使用可变状态——只要它不是共享的,您仍然可以避免共享可变状态。

最新更新