纯度与参考透明度

Ani*_*Ani 58 language-agnostic functional-programming side-effects referential-transparency purely-functional

这些术语似乎有 不同的定义,但我总是想到一个暗示另一个; 当表达式是引用透明但不纯粹时,我无法想到任何情况,反之亦然.

维基百科为这些概念维护单独的文章并说:

参考透明度:

如果表达式中涉及的所有函数都是纯函数,则表达式是引用透明的.此外,如果丢弃它们的值并且它们的副作用无关紧要,则表达式中可以包含一些不纯的函数.

来自纯粹的表达:

构造纯表达式需要纯函数.[...]纯表达通常被称为引用透明.

我发现这些陈述令人困惑.如果副作用所谓的"非纯函数"是微不足道的,足以让不执行他们(即替换其这种函数的调用没有实质性改变程序),它是一样的,如果它的是纯粹的第一名,不是吗?

有没有更简单的方法来理解纯表达式和引用透明的表达式之间的差异(如果有的话)?如果存在差异,则可以理解清楚地表明它的示例表达.

Nor*_*sey 43

如果我在一个地方聚集了我认识的三位理论家,其中至少有两位不同意"参照透明度"一词的含义.当我还是一名年轻学生时,我的导师给了我一篇论文,解释说即使你只考虑专业文献,"引用透明"这个短语也用来表示至少三种不同的东西.(不幸的是,这篇论文是在一盒尚未被扫描的重印版中的某个地方.我搜索了Google学术搜索,但我没有成功.)

我不能告诉你,但我可以建议你放弃:因为即使是那些尖头语言理论家的小干部也不能就它的意思达成一致,"引用透明"一词也没用.所以不要使用它.


PS关于与编程语言的语义有关的任何主题,维基百科都是不可靠的.我放弃了试图解决它; 维基百科的过程似乎关注稳定性和准确性的变化和普遍投票.

  • 说得好!事实上,我可能会注意到,维基百科本身也将引用的文章标记为不可靠,因为它们没有引用它们的来源.辩论这些文章的内容是徒劳的. (6认同)
  • 你的答案已经三年了,也许你提到的论文已经可以访问了。你能给我们报纸的名字吗? (2认同)

scl*_*clv 7

所有纯函数都必须是引用透明的.因为根据定义,他们无法访问除了传递内容之外的任何内容,因此他们的结果必须完全由他们的参数决定.

但是,有可能具有不纯粹的引用透明功能.我可以编写一个赋予int的函数i,然后生成一个随机数r,r从自身中减去并将其放入s,然后返回i - s.很明显,这个功能是不纯的,因为它产生随机数.但是,它是参考透明的.在这种情况下,这个例子很愚蠢和做作.但是,在例如Haskell中,id函数是类型的,a - > a而我的stupidId函数是a -> IO a指示它利用副作用的类型.当程序员可以通过外部证明保证他们的功能实际上是引用透明的时候,那么他们可以unsafePerformIO用来剥离IO背面的类型.

  • 但是,如果它改变了全局随机生成器的状态,则它不是引用透明的 - 用函数调用(在调用站点)替换它的值会给你一个不同的程序.没有? (3认同)
  • 所以你说`int func(int i){int r = rand(); int s = r - r; 回归i - s; }`是引用透明而不是纯粹的,因为它"它生成随机数"?它为什么不纯?它总是为同一个参数返回相同的结果,并且确实会导致任何可观察到的副作用.另一方面,如果对`rand()`*的调用*有副作用(让我们说它改变了*全局*随机数生成器的状态),它既不纯也不是引用透明.(如果我完全误解了你的帖子,请道歉.) (2认同)