Functional programming 将代码转换为纯函数形式

Functional programming 将代码转换为纯函数形式,functional-programming,automated-refactoring,Functional Programming,Automated Refactoring,从某种意义上说,任何命令式代码都可以通过使每个操作接收并传递“世界状态”参数而转换为纯函数形式 但是,假设您有一些几乎是纯函数形式的代码,除了隐藏了许多层函数调用之外,还有一些命令操作修改全局或至少广泛访问的状态,例如调用随机数生成器、更新计数器、打印一些调试信息,你想把它转换成纯函数形式,在算法上,用最少的变化 有没有一种方法可以做到这一点,而不必将整个程序翻过来?从技术上讲,这并不难 如果您只想避免修改全局状态,例如,使代码重新进入,那么对于读取X的任何副作用函数F,都会写入全局变量Y, 并

从某种意义上说,任何命令式代码都可以通过使每个操作接收并传递“世界状态”参数而转换为纯函数形式

但是,假设您有一些几乎是纯函数形式的代码,除了隐藏了许多层函数调用之外,还有一些命令操作修改全局或至少广泛访问的状态,例如调用随机数生成器、更新计数器、打印一些调试信息,你想把它转换成纯函数形式,在算法上,用最少的变化


有没有一种方法可以做到这一点,而不必将整个程序翻过来?

从技术上讲,这并不难

如果您只想避免修改全局状态,例如,使代码重新进入,那么对于读取X的任何副作用函数F,都会写入全局变量Y, 并返回Z,将其转换为读取X的F',修改包含传递给它的Y的结构,然后返回Z。如果a调用B调用。。传递调用F, F修改全局Y,那么A'必须构建对包含Y的结构的引用,并将其传递给B。现在,所有函数只修改传递给它们的值;它们对全球国家没有副作用。(好吧,我们可以争论A的作用)

[有人可能会抱怨F所做的(文件/屏幕/设备)输出无法处理。好吧,要么你想立即对世界产生副作用,要么你不想。如果你不想,请将输出的“状态”添加为Y,并对其进行修改;A'可以作为结果返回所需的输出。]

如果您坚持要使程序正常运行,那么F对全局Y的任何副作用都已更改为传入Y,在将Y更改为生成Y'的同时复制Y,然后F'必须返回一对。F的调用者必须传入Y,并在可从调用站点访问的所有代码中使用生成的Y'

关于复制的一点让你陷入了真正的麻烦:做Y的深度复制的逻辑在哪里?如果您找到了它,您可能会发现deepcopy产生了一个巨大的结构,您的存储需求很快变得不可能。现在,您需要找到一种方法,让Y'共享Y中未更改的部分

现在,如果你想在一个大代码上完成这两项任务中的任何一项,你可能不想手工完成;人们不善于处理这种细节,他们想欺骗/重写/。。。如果你真的想这样做,你需要一个可以机械地应用必要步骤的


我将注意到,标准编译技术将程序转换为所谓的“静态单赋值(SSA)”形式,它将IR中表示的尽可能多的程序转换为函数程序,因为它更容易转换/优化。他们仍然担心全局存储。

你是说你的程序有副作用吗?@OliverCharlesworth是的。只有一小部分代码行有副作用,但它们被深埋在函数调用的许多层中,我想自动将其转换为一个没有副作用的程序,同时尽可能保留原始结构。你的意思是,找到执行副作用的行并删除它们?@Bergi no,转换必须保留节目的意义。副作用是节目意义的一部分。举一个例子,在“打印一些调试信息”的情况下,您希望转换的最终结果是什么?