纯操作调用可能不是引用透明的?
Pure operation call may not be referentially transparent?
当我尝试对序列的前两个元素使用纯操作时收到此警告。
代码看起来像这样:
class A
functions
public func: Seq -> bool
func(sq) == (
(hd sq).pureOperation() inter (hd (tl sq)).pureOperation() <> {}
);
end A
它会导致警告:“纯操作调用可能不是引用透明的”并且 Overture 在 hd
函数下方放置了波浪形的黄线。
导致此警告的原因是什么?我该怎么办?
此警告是在将纯操作添加到语言定义时引起大量争论的结果。问题是,最终,即使一个操作被标记为纯操作(并遵守所有遵循的规则),我们也不能确定使用相同参数调用该操作将始终产生相同的值。这是函数中引用透明性所必需的,因此我们会发出警告。
仅当从函数调用纯操作时才会出现警告,但如果必须这样做,则无法避免警告。
例如,考虑以下 - pure_i 操作是 "pure",因为它只是 return 一个状态值,但该状态可以通过 not_transparent 操作,因此函数 f(x) 将 return 相同参数的不同值:
class A
instance variables
static public i : nat := 0
operations
static public pure pure_i : () ==> nat
pure_i() == return i;
functions
f : nat -> nat
f(x) == pure_i() + x;
operations
static public not_transparent : () ==> ()
not_transparent() == (
i := 1;
);
end A
当我尝试对序列的前两个元素使用纯操作时收到此警告。
代码看起来像这样:
class A
functions
public func: Seq -> bool
func(sq) == (
(hd sq).pureOperation() inter (hd (tl sq)).pureOperation() <> {}
);
end A
它会导致警告:“纯操作调用可能不是引用透明的”并且 Overture 在 hd
函数下方放置了波浪形的黄线。
导致此警告的原因是什么?我该怎么办?
此警告是在将纯操作添加到语言定义时引起大量争论的结果。问题是,最终,即使一个操作被标记为纯操作(并遵守所有遵循的规则),我们也不能确定使用相同参数调用该操作将始终产生相同的值。这是函数中引用透明性所必需的,因此我们会发出警告。
仅当从函数调用纯操作时才会出现警告,但如果必须这样做,则无法避免警告。
例如,考虑以下 - pure_i 操作是 "pure",因为它只是 return 一个状态值,但该状态可以通过 not_transparent 操作,因此函数 f(x) 将 return 相同参数的不同值:
class A
instance variables
static public i : nat := 0
operations
static public pure pure_i : () ==> nat
pure_i() == return i;
functions
f : nat -> nat
f(x) == pure_i() + x;
operations
static public not_transparent : () ==> ()
not_transparent() == (
i := 1;
);
end A