该术语是什么意思 参考透明度 意思是?我听说它被描述为“这意味着你可以用 equals 替换 equals”,但这似乎是一个不充分的解释。

有帮助吗?

解决方案

术语“参考透明度”来自分析哲学,这是哲学的分支,分析自然语言结构,陈述和论据基于逻辑和数学方法。换句话说,它是计算机科学以外最接近的主题,我们称之为编程语言语义。哲学家 Willard Quine 负责启动参考透明度的概念,但它也隐含在Bertrand Russell和Alfred Whitehead的方法。

其核心是“参考透明度”。是一个非常简单明了的想法。术语“指示物”是指“指示物”。用于分析哲学来谈论表达式所引用的东西。它与我们所说的“含义”大致相同。或“外延”或“外延”。在编程语言语义学中。使用Andrew Birkett的例子(博客文章),术语“苏格兰的首都”指的是爱丁堡市。这是“指示物”的直接例子。

句子中的上下文是“引用透明的”。如果在该上下文中用引用同一实体的另一个术语替换术语不会改变含义。例如

  

苏格兰议会在苏格兰首都举行会议。

相同
  

苏格兰议会在爱丁堡举行会议。

所以上下文“苏格兰议会在......会面”。是一个参考透明的背景。我们可以取代“苏格兰的首都”。与“爱丁堡”一起没有改变意义。换句话说,上下文只关心术语所指的内容,而不关心其他内容。这就是上下文“引用透明”的意义。

另一方面,在句子中,

  

自1999年以来,爱丁堡一直是苏格兰的首府。

我们不能做这样的替代。如果我们这样做,我们会得到“爱丁堡自1999年以来一直是爱丁堡”,这是一个可怕的说法,并没有表达与原句相同的含义。因此,似乎“爱丁堡自1999年以来”的背景一直是“是参考不透明的(与参考透明相反)。它显然更关心更多而不是术语所指的东西。它是什么?

诸如“苏格兰首都”之类的东西。被称为明确的术语,他们长期以来没有给逻辑学家和哲学家带来过少的头痛。 Russell和Quine将它们排除在外,说它们实际上并不是“参照”,即认为上述例子用于指代实体是错误的。正确理解“爱丁堡自1999年以来一直是苏格兰的首都”是说

  苏格兰自1999年以来一直有资本,首都是爱丁堡。

这句话不能变成坚果。问题解决了!奎因的观点是说自然语言是混乱的,或者至少是复杂的,因为它被用来方便实际使用,但哲学家和逻辑学家应该以正确的方式理解它们。参考透明度是一种用于实现清晰度的工具。

这与编程有什么关系?实际上并不是很多。如我们说过,引用透明度是一种用于理解语言的工具,即分配含义。建立编程语言语义学领域的 Christopher Strachey 在他的意义研究中使用了它。他的基础论文“编程语言中的基本概念“可在网上找到。这是一篇精美的论文,每个人都可以阅读和理解它。所以,请这样做。你会得到很多启发。他引入了术语“参照透明度”。在本段中:

  

表达式最有用的属性之一是由Quine引用   透明度。实质上,这意味着如果我们希望fi nd表达式的值   包含一个子表达式,我们唯一需要知道的关于子表达式的是它   值。子表达式的任何其他功能,例如其内部结构,数量   和组件的性质,评估的顺序或墨水的颜色   它们的编写方式与主要表达的价值无关。

使用“本质上”表明Strachey正在解释它,以简单的方式解释它。功能程序员似乎以自己的方式理解这一段。还有9个其他出现的“参考透明度”。在论文中,但他们似乎并不打扰任何其他人。实际上,Strachey的全文都致力于解释命令式编程语言的含义。但是,今天,功能程序员声称命令式编程语言引用透明。 Strachey会在他的坟墓中转身。

我们可以挽救局势。我们说自然语言是“凌乱的,或者至少是复杂的”。因为它便于实际使用。编程语言是一样的。它们是“凌乱的,或者至少是复杂的”。因为它们使得便于实际使用。这并不意味着他们需要混淆我们。他们只需要以正确的方式理解它们,使用一种引用透明的元语言,这样我们就可以清晰地理解它们。在我引用的论文中,Strachey正是如此。他通过将命令式编程语言分解为基本概念来解释命令式语言的含义,从不在任何地方失去清晰度。他的分析的一个重要部分是指出编程语言中的表达式有两种“值”,称为 l-values r-values 。在Strachey的论文之前,这一点并未得到理解,并且混乱占据了至高无上的地位。今天,C的定义经常提及它,每个C程序员都理解这种区别。 (其他语言的程序员是否同样理解它很难说。)

Quine和Strachey都关注语言结构的含义,这些语言结构涉及某种形式的背景依赖。例如,我们的例子“爱丁堡自1999年以来一直是苏格兰的首都”。表示“苏格兰首都”的事实。取决于它被考虑的时间。无论是在自然语言还是编程语言中,这种上下文依赖都是现实。即使在函数式编程中,自由和绑定变量也要根据它们出现的上下文进行解释。任何类型的上下文依赖性都会以某种方式阻止引用透明性。如果你试图理解术语的含义而不考虑它们所依赖的上下文,你将再次结束w

其他提示

参考透明度是函数式编程中常用的术语,意味着给定函数和输入值,您将始终获得相同的输出。也就是说,函数中没有使用外部状态。

以下是参照透明函数的示例:

int plusOne(int x)
{
  return x+1;
}

使用参照透明函数,给定输入和函数,您可以用值替换它而不是调用函数。因此,我们不能用参数5来调用plusOne,而是用6替换它。

另一个很好的例子是数学。在给定函数和输入值的数学中,它将始终映射到相同的输出值。 f(x)= x + 1.因此,数学中的函数是参考透明的。

这个概念对研究人员很重要,因为它意味着当你有一个引用透明功能时,它有助于简化自动并行化和缓存。

参考透明度总是在Haskell等函数式语言中使用。

-

相比之下,存在参照不透明的概念。这意味着相反的情况。调用该函数可能并不总是产生相同的输出。

//global G
int G = 10;

int plusG(int x)
{//G can be modified externally returning different values.
  return x + G;
}

另一个例子是面向对象编程语言中的成员函数。成员函数通常对其成员变量进行操作,因此是引用不透明的。成员函数当然可以是引用透明的。

另一个例子是从文本文件中读取并打印输出的函数。此外部文本文件可能随时更改,因此该函数将是引用不透明的。

引用透明函数是仅依赖于其输入的函数。

[这是我 3 月 25 日回答的后记,旨在使讨论更接近函数式/命令式编程的关注点。]

函数式程序员的引用透明性想法似乎与标准概念在三个方面有所不同:

  • 而哲学家/逻辑学家使用“指称”、“表示”、“指定”和“意思”(弗雷格的德语术语),函数式程序员使用术语“值”。(这并不完全是他们做的。我注意到兰丁、斯特拉奇和他们的后代也使用“值”这个术语来谈论指称/外延。这可能只是兰丁和斯特雷奇引入的术语简化,但如果以简单的方式使用,它似乎会产生很大的差异。)

  • 函数式程序员似乎相信这些“值”存在于编程语言内部,而不是外部。在这一点上,他们不同于哲学家和编程语言语义学家。

  • 他们似乎相信这些“价值”应该是通过评估获得的。

例如,维基百科上的文章 参考透明度 今天早上说:

如果表达式可以用它的值替换而不改变程序的行为(换句话说,在相同的输入上产生具有相同效果和输出的程序),则称该表达式是引用透明的。

这与哲学家/逻辑学家的说法完全不一致。他们说,如果上下文中的表达式可以被另一个表达式替换,则上下文是引用的或引用透明的 表达 指的是同一件事(a 共指 表达)。这些哲学家/逻辑学家是谁?他们包括 弗雷格, 拉塞尔, 怀特海德, 卡尔纳普, 蒯因, 教会 以及无数其他人。他们每一个都是一个高耸的人物。这些逻辑学家的综合智力至少可以说是惊天动地的。他们一致认为所指/指称存在于形式语言之外,而语言内的表达只能说话。 关于 他们。因此,人们在语言中所能做的就是用引用同一实体的另一个表达式替换一个表达式。指称/指代本身 不要 存在于语言之中。为什么函数式程序员会背离这个既定的传统呢?

人们可能会认为编程语言语义学家可能误导了他们。但是,他们没有。

着陆:

(a)每个表达式都有一个嵌套的亚表达结构,(b)每个亚表达 表示某物(通常是数字,真实价值或数值功能), ,(c)表达式表示的事物,即“值”,仅取决于其子表的值,而不取决于其其他属性。[增加强调]

斯托伊:

关于表达的唯一重要的是其价值,任何子表达都可以替换为 任何其他同等价值的 [增加强调]。此外,在一定限度内,表达式的值无论何时出现都是相同的”。

伯德和瓦德勒:

表达式的值仅取决于其成分表达式的值(如果有),这些子表达可以自由地替换为 其他具有相同价值的人 [增加强调]。

因此,回想起来,兰丁和斯特雷奇通过用“价值”取代“参考”/“表示”来简化术语的努力可能是不明智的。人们一听到“价值”,就会忍不住想到一个导致它的评估过程。同样很容易将评估产生的任何内容视为“值”,即使很明显这不是外延。这就是我认为在函数式程序员眼中“引用透明度”概念所发生的情况。但早期语义学家所说的“价值”是 不是 评估的结果或函数的输出或任何类似的东西。这是该术语的外延。

一旦我们将表达式的所谓“值”(古典哲学家话语中的“指称”或“外延”)理解为一个复杂的数学/概念对象,各种可能性就会出现。

  • Strachey 将命令式编程语言中的变量解释为 L值, ,正如我在 3 月 25 日的回答中提到的,这是一个复杂的概念对象,在编程语言的语法中没有直接表示。
  • 他还将这种语言中的命令解释为状态到状态函数,这是复杂数学对象的另一个实例,它不是语法中的“值”。
  • 即使是 C 中的副作用函数调用也有一个明确定义的“值”作为状态转换器,将状态映射到状态和值对(函数程序员术语中所谓的“monad”)。

函数式程序员不愿意称这种语言为“引用透明”,仅仅意味着他们不愿意承认这种复杂的数学/概念对象作为“值”。另一方面,当状态转换器被放入他们自己喜欢的语法并用“monad”这样的流行词装饰时,他们似乎非常愿意将状态转换器称为“值”。我不得不说,即使我们承认他们的“引用透明度”想法具有一定的一致性,他们也是完全不一致的。

回顾一下历史或许可以让我们了解这些混乱是如何产生的。1962 年至 1967 年对于 Christopher Strachey 来说是非常紧张的时期。1962 年至 65 年间,他在莫里斯·威尔克斯 (Maurice Wilkes) 那里兼职担任研究助理,设计并实现了后来被称为 CPL 的编程语言。这是一种命令式编程语言,但也具有强大的函数式编程语言功能。Landin 是 Strachey 咨询公司的员工,他对 Strachey 对编程语言的看法产生了巨大影响。在 1965 年具有里程碑意义的论文中“接下来的 700 种编程语言”,Landin 毫不掩饰地推广函数式编程语言(称它们为函数式编程语言) 外延的 语言)并将命令式编程语言描述为它们的“对立面”。在随后的讨论中,我们发现斯特雷奇对兰丁的强势地位提出了质疑。

...DLS构成所有语言的子集。它们是一个有趣的子集,但是除非您已经习惯,否则使用它是不便的。我们需要它们,因为 眼下 我们不知道如何用包括必要和跳跃在内的语言构建证据。[增加强调]

1965 年,斯特雷奇担任牛津大学讲师,似乎基本上全职致力于发展命令式和跳跃理论。到 1967 年,他已经准备好一种理论,并在他的课程中教授“编程语言的基本概念“在哥本哈根暑期学校。该讲义应该发表,但“不幸的是,由于扩张性编辑,诉讼从未实现;但是,像Strachey在牛津的大部分工作一样,该论文具有影响力的私人流通。马丁·坎贝尔-凯利)

获得斯特雷奇著作的困难可能导致混乱的传播,人们依赖二手资料和道听途说。但是,现在“基础概念“在网络上很容易获得,无需进行猜测。我们应该阅读它并就斯特雷奇的意思做出自己的判断。尤其:

  • 在第 3.2 节中,他讨论了“表达式”,其中谈到了“R 值引用透明度”。
  • 他的第 3.3 节涉及“命令”,其中谈到“L 值引用透明度”。
  • 在第3.4.5节中,他讨论了“函数和例程”,并宣布“ R值参考透明在R值上下文中的任何偏离都应通过将表达式分解为几个命令和更简单的表达式来消除,或者,如果事实证明这很困难,这是评论的主题。”

任何在不理解 L 值、R 值和填充命令式程序员概念世界的其他复杂对象之间的区别的情况下谈论“引用透明度”都是根本上的错误。

如果表达式可以替换为其值而不更改算法,则表达式是引用透明的,从而产生在同一输入上具有相同效果和输出的算法。

引用透明函数是一种充当数学函数的函数;给定相同的输入,它将始终产生相同的输出。这意味着传入的状态不会被修改,并且该函数没有自己的状态。

如果你对词源感兴趣(即为什么这个概念有这个特定的名字),请看看我的博客文章。术语来自哲学家/逻辑学家奎因。

对于那些需要简明解释的人,我会冒一个(但请阅读下面的披露)。

编程语言中的参照透明度促进了等式推理 - 您拥有的参考透明度越高,就越容易进行等式推理。例如。使用(伪)函数定义,

f x = x + x,

在此定义的范围内,您可以(安全地)使用foo + foo替换f(foo),而不会对执行此减少的位置有太多限制,这很好地表明参考透明度有多大你的编程语言有。

例如,如果foo是C编程意义上的x ++,那么你就无法安全地执行这种减少(也就是说,如果你要执行这种减少,你将不会得到你开始使用的相同程序)

在实用的编程语言中,你不会看到完美的参考透明度,但功能程序员比大多数人更关心它(参见Haskell,它是一个核心目标)。

(完全披露:我是一名功能性程序员,所以在最佳答案中你应该用一点点解释。)

  1. 指称语义基于建模语言,通过构建构成可指称的域 价值观.
  2. 函数式程序员使用这个术语 价值 描述基于语言重写规则的计算的收敛性,即。它的操作语义。

在 1 中,有问题的两种语言的清晰度:

  • 被建模的对象语言
  • 建模语言,元语言

2、由于对象和元语言的接近性,它们可能会被混淆。

作为一名语言实现者,我发现我需要不断记住这种区别。

所以教授。雷迪,我可以这样解释你吗:-)

在函数式编程和语义的上下文中,术语 参照透明度 不是参照透明的。

我希望以下答案增加并证明有争议的第一和第三 答案。

让我们授予表达式表示或引用 一些指称。然而,一个问题是这些指示物是否可以作为表达式本身的一部分同构编码,称这些表达式为“值”。例如,文字数值是算术表达式集的子集,真值是布尔表达式集的子集,等等。想法是将表达式计算为其值(如果有的话)。因此,“值”一词可以指代表达式或表达式集合中的区分元素。但是如果指示对象和值之间存在同构(双射) 可以说他们是一回事。 (这就是说,必须谨慎定义 指称领域所证明的指称和同构 语义。举一个回答第三个回答的例子来说, 代数数据类型定义数据Nat = Zero | Suc Nat 没有 对应于自然数的集合。)

让我们为带有洞的表达式编写 E [&#183;] ,在某些方面也称为 作为'背景'。类似C的表达式的两个上下文示例是 [&#183;] + 1 和 <代码> [&#183;]。++

让我们为带有表达式的函数编写 [[&#183;]] (没有空洞) 并在某些方面传达其含义(指称,指示等) 提供意义的宇宙。 (我正在借用现场的记号 指称语义学。)

让我们在一定程度上正式调整Quine的定义如下:上下文 E [&#183;] 如果给出任何两个表达式 E1 E2 (无孔),则引用是透明的 这样 [[E1]] = [[E2]] (即表达式表示/指代 相同的指示物)那么 [[E [E1]]] = [[E [E2]]] (即填写) 带有 E1 E2 的洞会产生同样表示相同的表达式 所指)。

Leibniz将equals代入等于的平均值通常表示为“if” E1 = E2 然后 E [E1] = E [E2] ',表示 E [&#183;] 是一个函数。一个功能 (或者就此而言,计算函数的程序)是来自a的映射 源到目标,以便每个源最多有一个目标元素 元件。非确定性函数是用词不当,它们要么是关系, 如果在莱布尼兹的规则中,等式 = 是 然后双括号被认为是理所当然的 省略。因此,引用透明的上下文是一种功能。而莱布尼茨的规则是等式推理的主要成分,因此等式推理肯定与参照透明度有关。

虽然 [[&#183;]] 是一个从表达到表示的函数,但它可能是一个 函数从表达式到“值”被理解为受限制的子集 表达式和 [[&#183;]] 可以理解为评估。

现在,如果 E1 是一个表达式并且 E2 是一个值,我认为大多数人在根据表达式,值,定义参照透明度时的意思是,和评估。但正如本页第1和第3个答案所示,这是一个不明确的定义。

诸如 [&#183;] ++ 之类的上下文的问题不是副作用,而是它的值没有在C中同义地定义为其含义。功能是 不是值(嗯,指向函数的指针),而在函数式编程语言中它们是。着陆, Strachey和指称语义学的先驱们非常聪明 使用功能世界来提供意义。

对于命令式C语言,我们可以(粗略地)提供语义 expre

注意这个“含义”的概念。是在观察者心中发生的事情。因此,相同的“参考”是指“参考”。可以对不同的人意味着不同的东西。因此,例如,我们在维基百科上有一个爱丁堡消歧页面。

可能出现在编程环境中的相关问题可能是多态性。

也许我们应该为多态(或者甚至是铸造)的特殊情况命名,其中为了我们的目的,不同的多态情况在语义上是等价的(而不是仅仅是相似的。例如,数字1 - 哪个可以用整数类型,或复杂类型或任何其他各种类型表示 - 可以多态处理。

我在书中找到了引用透明度的定义“计算机程序的结构和实现” (向导书)很有用,因为它通过引入赋值操作来解释引用透明度的方式得到补充。查看我对该主题所做的以下幻灯片: https://www.slideshare.net/pjschwarz/introducing-assignment-invalidates-the-substitution-model-of-评价和 - 违反指涉透明度-作为说明的功能于SiC颗粒最向导书

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top