纯度vs参考透明度

这些术语似乎有不同的定义 ,但我总是想到一个意味着另一个; 我不能想到任何情况下,一个expression是透明的,但不是纯粹的,反之亦然。

维基百科针对这些概念维护不同的文章,并说:

从参考透明度 :

如果expression式中涉及的所有函数都是纯函数,那么expression式就是透明的。 另外,如果expression式中包含一些不纯的函数,那么它们的值将被丢弃,并且其副作用不明显。

从纯粹的表情 :

纯函数是构造纯expression式所必需的。 纯粹的expression通常被认为是透明的。

我觉得这些陈述混淆。 如果来自所谓的“不纯function”的副作用不足以允许不执行它们(即,用它的replace对这样的function的调用),而不实质上改变程序,则它就像在第一个地方,不是吗?

有没有更简单的方法来理解纯粹的expression和透明的expression之间的区别? 如果有差异,清楚地表明它的示例expression将不胜感激。

如果我认识三位熟识的理论家,其中至less有两位对“参照透明”一词的含义不一致。 而当我还是一个年轻的学生时,我的一位导师给了我一份文件,解释说即使你只考虑专业文献,“引用透明”这个词也是指至less三种不同的东西。 (不幸的是,纸张是在一个重印的盒子里,还没有被扫描。我搜查了Google Scholar,但我没有成功。)

我不能通知你,但我可以build议你放弃:因为即使是尖头的语言理论家的微小干部也不能认同它的含义,所以“透明地”是没有用的 。 所以不要使用它。


PS在任何与编程语言的语义有关的话题上,维基百科都是不可靠的。 我已经放弃了试图解决这个问题。 维基人的进程似乎把改变和普遍的投票视为稳定和准确。

所有纯粹的function必然是透明的。 因为根据定义,他们不能访问除了他们传递的东西以外的东西,他们的结果必须完全由他们的论点决定。

然而,可能具有不纯粹的引导透明function。 我可以编写一个函数给i一个int,然后生成一个随机数r ,从它自己减去r ,并把它放在s ,然后返回i - s 。 很明显,这个函数是不纯的,因为它产生的是随机数。 但是,它是透明的。 在这种情况下,这个例子是愚蠢的和人为的。 然而,在Haskell中, id函数的typesa - > a而我的stupidId函数的typesa -> IO a表示它使用了副作用。 当程序员可以通过外部certificate保证它们的函数实际上是透明的,那么他们可以使用unsafePerformIO来将IO从types中去除。

我有些不确定我在这里给出的答案,但肯定会有人指出我们的方向。 🙂

“纯度”通常被认为是指“缺乏副作用”。 如果评价缺乏副作用,则表示被认为是纯粹的。 那么什么是副作用呢? 在一个纯粹的function语言中,副作用就是任何不由简单的beta规则去执行的规则(评估函数应用的规则与用forms参数的所有空闲事件replace实际参数相同)。

例如,在一个具有线性(或唯一性)的函数式语言中,这个区别在这个时候不应该打扰)types允许一些(受控)的变异。

所以我想我们已经弄清了“纯度”和“副作用”可能是什么。

参考透明度(根据您引用的维基百科文章)意味着variables可以被它表示的expression(缩写,代表)所替代,而不会改变程序的意义(这也是一个难以解决的问题,我不会在这里尝试这样做)。 因此,“纯粹”和“参照透明”确实是不同的东西:“纯粹”是一些expression的属性,大致意思是“执行时不产生副作用”,而“参照透明”是与variables和expression有关的性质它代表和意思是“variables可以用它所表示的”代替。

希望这有助于。

一个ACCU2015演讲的这些幻灯片对参考透明度的话题进行了很好的总结。

从幻灯片之一:

如果(a)每一个子expression式都可以被任何与其相等的值所代替,并且(b)给定上下文中所有出现的expression式都产生相同的值,那么语言就是透明的。

例如,你可以有一个函数将其计算logging到程序的标准输出中(所以它不会是一个纯函数),但是你可以用一个类似的函数来替代这个函数的调用, 。 所以这个函数具有参照透明属性。 但是……上面的定义是关于语言的,而不是expression式,就像幻灯片所强调的那样。

[…]就好像它是纯粹的一样,不是吗?

根据我们的定义,不,它不是。

有没有更简单的方法来理解纯粹的expression和透明的expression之间的区别?

试试我上面提到的幻灯片 。

我将引用约翰·米切尔(John Mitchell)在“ 编程语言中的概念”一书中所写的内容 我不记得它一行一行,但他定义纯粹的function语言必须通过声明性语言testing是:

“在x1,…,xn的特定减速范围内,所有只包含variablesx1,…,xn的expression式e具有相同的值。

总之,其他人提到没有副作用或没有副作用(副作用“缺乏”)。

在语言学中,如果一个名词或名词短语可能被另一个具有相同指称的名词短语所取代,而不改变它所包含的句子的含义,则该名词或名词短语被认为是相对透明的。

在第一种情况下,但在第二种情况下,这太奇怪了。

案例1:“我看到沃尔特进入他的新车 。”

如果沃尔特拥有一个Centro,那么我们可以用下面的语句replace它:

“我看到沃尔特进入他的Centro

与第一个相反:

案例2:因为他的胡子,他被称为威廉·鲁弗斯William Rufus)

鲁弗斯意味着有些红色,并提到英格兰的威廉四世。

“他因为读了胡子而被称为威廉四世 。” 看起来太尴尬了。

传统的说法是,如果我们可以在不改变程序的含义的情况下,用程序中任何地方的一个相同值replace一个expression,语言就是透明的。

所以,参照透明是纯粹function语言的一个属性。 如果你的程序没有副作用,那么这个属性将保留。

所以放弃是非常好的build议,但在这方面也可能看起来不错。