- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
DateTime.Now或Date.now是引用透明的吗?
这是Qiita中的函数式编程文章中有争议的主题之一。
首先,我们必须非常小心,因为“参照透明”一词在某种意义上是棘手的词/概念,并且在
What is referential transparency?
发问者称:
参照透明性一词是什么意思?我听说它被描述为“这意味着您可以用相等替换相等”,但这似乎是一个不足的解释。
一个非常典型的解释,但通常会导致我们误解的想法如下:(上一页的#2答案,@ Brian R. Bondy)
引用透明性,是函数编程中常用的术语,表示给定功能和输入值,您将始终收到相同的输出。也就是说,函数中没有使用外部状态。
我一直听到并认为错误的典型主张是这样的:
在编程语言中,Date.now
始终返回与当前时间相对应的不同值,并且根据
给定一个函数和一个输入值,您将始终收到相同的输出。
因此,Date.now
不是参照透明的!
我知道一些(函数式)程序员坚信上述主张是可信的,但是,@ Uday Reddy给出的#1和#3回答如下:
从根本上讲,在不理解L值,R值和其他构成命令式程序员概念范围的复杂对象之间的区别的情况下,谈论“参照透明性”是错误的。
函数式程序员的引用透明性概念似乎与标准概念在以下三个方面有所不同:
哲学家/逻辑学家使用诸如“引用”,“表示”,“ designatum”和“ bedeutung”(弗雷格的德语术语)之类的术语,而功能程序员则使用“值”一词。 (这不完全是他们的工作。我注意到,Landin,Strachey及其后代也使用“值”一词来谈论参考/表示。这可能只是Landin和Strachey引入的术语简化,但似乎使如果以幼稚的方式使用,则差异很大。)
函数式程序员似乎认为这些“值”存在于编程语言中,而不是外部。在此过程中,他们既不同于哲学家,也不同于编程语言语义学家。
他们似乎认为这些“值”应该通过评估获得。
想到这一点,“外部状态”也是一个棘手的词/概念。
引用透明性,是函数编程中常用的术语,表示给定功能和输入值,您将始终收到相同的输出。也就是说,函数中没有使用外部状态。
是“当前时间”是“外部状态”还是“外部价值”?
如果我们称“当前时间”为“外部状态”,那么“鼠标事件”呢?
“鼠标事件”不是应该由编程上下文管理的状态,而是一个外部事件。
给定一个函数和一个输入值,您将始终收到相同的输出。
因此,我们可以理解如下:
“当前时间”既不是“输入值”也不是“外部值”也不是“外部状态”,并且Date.now
始终返回与正在进行的事件“当前时间”相对应的相同输出。
如果仍然坚持或想将“当前时间”称为“值”,那么,
函数式程序员似乎认为这些“值”存在于编程语言中,而不是外部。在此过程中,他们既不同于哲学家,也不同于编程语言语义学家。
“当前时间”的值从不存在于编程语言中,而仅存在于外部,而“外部时间”的值显然不是通过编程上下文而是通过真实世界的时间流来更新的。
因此,我了解Date.now是引用透明的。
我想读一下你的想法。谢谢。
编辑1
在
What is (functional) reactive programming?
Conal Elliott @Conal还解释了功能反应编程(FRP)。
他是最早开发FRP的人之一,他这样解释:
FRP是关于-“代表“时间”值的数据类型”
动态/不断变化的值(即“随时间变化的值”)本身就是一等值。
从FRP的角度来看,Date
可以看作是“随时间变化”的一等值,它是时间轴上的不变对象。.now
是用于在Date
中解决“当前时间”的属性/功能
因此,Date.time
返回表示我们“当前时间”的不可变和参照透明值。
编辑2
(在JavaScript中)
参照不透明函数
let a = 1;
let f = () => (a);
Function:f
的输入为none;
Function:f
的输出取决于
a
,后者取决于
f
以外的上下文
let t = Date.now();
let f = (Date) => (Date.now());
Date
值存在于我们的物理世界中,但
Date
可以看作是“随时间推移”不变的FRP一流值。
Date
都是相同的,因此我们通常会隐式地省略
Date
作为输入值,就像
let f = () => (Date.now());
Date.now
是参照透明的。它始终表示“当前时间”。
Date.now()
不是,它是一个函数调用,根据外部状态返回不同的数字。具有参照透明性的“当前时间的概念”的问题在于我们无法用它来计算任何东西。
Date.now()
相同。
Date.now
函数/获取器,该函数始终返回程序启动的时间(就像程序立即执行一样),但这不是
Date.now()/Date.Now
的工作方式。它们取决于程序的执行状态。 –贝吉
Date.now
是参照透明的。
Date.now()
(带有执行/评估)在不同的时间返回“不同的值”,并且不再是参照透明的。我们尚未达成共识。
console.log(Date.now()); //some numeric for 2016/05/18 xx:xx:xx ....
console.log(Date.now()); //different numeric for 2016/05/18 xx:xx:xx ....
Date.now()
不是参照透明的。
const f = () => (Date.now());
f
在某些“事件驱动”上下文中进行评估。这就是功能编程代码的行为方式。
const f = Date.now;
Date.now
或
Date.now()
(具有执行/求值)从没有问题,可以在不同的时间返回“不同的值”。
最佳答案
好吧,我要对此采取行动。我不是这方面的专家,但是我花了一些时间思考您链接到的@UdayReddy's answers to this question,我想我对此深信不疑。
分析哲学中的参照透明
我认为您必须从雷迪先生回答其他问题的位置开始。雷迪先生写道:
在分析哲学中,术语“指代物”用于谈论表达式所指的东西。它与我们在编程语言语义中所说的“含义”或“表示”大致相同。
注意单词“ denotation”的使用。编程语言具有语法或语法,但也具有语义或含义。 Denotational semantics是将语言的语法翻译成其数学含义的实践。
据我所知,指称语义虽然未被广泛理解,但它是围绕计算机程序进行理解,设计和推理的最强大的工具之一。我要花一点时间为您的问题的答案奠定基础。
指称语义:将语法映射到意义
指称语义背后的思想是,计算机语言中的每个语法元素都具有对应的数学含义或语义。指称语义是语法和语义之间的显式映射。取语法数字1
。您可以将其映射为其数学含义,即数学数字1
。语义函数可能如下所示:
syntax
↓
⟦1⟧ ∷ One
↑
semantics
1
被拼写为
One
。这些只是指示我们何时谈论语义以及何时谈论语法的工具。您可以将该函数读为“语法符号
1
的含义是数字
One
”。
1
表示
One
。还有什么意思呢?但这不是必须的。您可以这样做:
⟦1⟧ ∷ Four
x
求平方的函数的表示法:
⟦square x⟧ ∷ λx → x²
var x = 0
func changeX() -> Int {
x += 1
return x
}
s
和一个产生新状态
s'
的函数,该符号可能看起来像这样,尽管我不知道这在数学上是否正确:
⟦changeX⟧ ∷ λs → (s → s')
changeX
函数的真正语义是什么,我也知道,如果我有另一个具有相同语义的术语,则可以将其中一个换成另一个。
Date.now
呢?
Date.now
的指称语义是什么,或者从数学意义上讲它的含义是什么。它是参照透明的吗?是的,我确定是的,因为它可以被具有相同语义的另一个函数替换。但是我不知道如何评估该函数的语义,因此,作为程序员,其引用透明性对我没有用。
关于functional-programming - Date.now引用透明吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37244023/
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: template pass by value or const reference or…? 以下对于将函数
我用相同的参数列表重载了一个运算符两次。但返回类型不同: T& operator()(par_list){blablabla} const T& operator()(par_list){bla
假设我有实现接口(interface) I 的 Activity A。我的 ViewModel 类 (VM) 持有对实现接口(interface) I 的对象的引用: class A extends
PHP 如何解释 &$this ?为什么允许? 我遇到了以下问题,这看起来像是 PHP 7.1 和 7.2 中的错误。它与 &$this 引用和跨命名空间调用以及 call_user_func_arr
谁能解释一下下面“&”的作用: class TEST { } $abc =& new TEST(); 我知道这是引用。但是有人可以说明我为什么以及什么时候需要这样的东西吗?或者给我指向一个对此有很好解
引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。 C++ 引用 vs 指针 引用很容易与指针混淆,它们之间有三
目录 引言 背景 结论 引言 我选择写C++中的引用是因为我感觉大多数人误解了引用。而我之所以有这个感受是因为我主持过很多C++的面试,并且我很少
Perl 中的引用是指一个标量类型可以指向变量、数组、哈希表(也叫关联数组)甚至函数,可以应用在程序的任何地方 创建引用 定义变量的时候,在变量名前面加个 \,就得到了这个变量的一个引用 $sc
我编写了一个将从主脚本加载的 Perl 模块。该模块使用在主脚本中定义的子程序(我不是维护者)。 对于主脚本中的一个子例程,需要扩展,但我不想修补主脚本。相反,我想覆盖我的模块中的函数并保存对原始子例
我花了几个小时试图掌握 F# Quotations,但我遇到了一些障碍。我的要求是从可区分的联合类型中取出简单的函数(只是整数、+、-、/、*)并生成一个表达式树,最终将用于生成 C 代码。我知道使用
很多时候,问题(尤其是那些标记为 regex 的问题)询问验证密码的方法。似乎用户通常会寻求密码验证方法,包括确保密码包含特定字符、匹配特定模式和/或遵守最少字符数。这篇文章旨在帮助用户找到合适的密码
我想通过 MIN 函数内的地址(例如,C800)引用包含文本的最后一个单元格。你能帮忙吗? Sub Set_Formula() ' ----------------------------- Dim
使用常规的 for 循环,我可以做类似的事情: for (let i = 0; i < objects.length; i++) { delete objects[i]; } 常规的 for-
在 Cucumber 中,您定义了定义 BDD 语法的步骤;例如,您的测试可能有: When I navigate to step 3 然后你可以定义一个步骤: When /^I navigate t
这是什么UnaryExpression的目的,以及应该怎样使用? 最佳答案 它需要一个 Expression对象并用另一个 Expression 包裹它.例如,如果您有一个用于 lambda 的表达式
给出以下内容 $("#identifier div:first, #idetifier2").fadeOut(300,function() { // I need to reference jus
我不知道我要找的东西的正确术语,但我要找的是一个完整的引用,可以放在双引号之间的语句,比如 *, node()、@* 以及所有列出的 here加上任何其他存在的。 我链接到的答案提供了一些细节,但还
This question's answers are a community effort。编辑现有答案以改善此职位。它当前不接受新的答案或互动。 这是什么? 这是常见问答的集合。这也是一个社区Wi
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
考虑下一个代码: fn get_ref(slice: &'a Vec, f: fn(&'a Vec) -> R) -> R where R: 'a, { f(slice) } fn m
我是一名优秀的程序员,十分优秀!