在 D 中记忆函数时,是否有任何巧妙的方法来保持纯度?
当缓存保存在 RAM 中的大型数据集的 SHA1 计算时,我想要这个。
在 D 中记忆函数时,是否有任何巧妙的方法来保持纯度?
当缓存保存在 RAM 中的大型数据集的 SHA1 计算时,我想要这个。
简短的回答:选择记忆或纯度。不要尝试两者兼得。
长答案:我不明白如何通过记忆保持纯度,除非你使用强制转换来欺骗编译器并声称一个函数pure
不是,因为为了记忆,你必须存储参数和结果破坏了纯度,因为pure
函数的第一保证是它们不访问可变的全局或静态变量(这是你能够记忆任何东西的唯一方法)。
所以,如果你做了类似的事情
alias pure nothrow Foo function() FuncType;
auto result = (cast(FuncType)&theFunc)();
那么您可以将theFunc
其视为pure
不是,但随后由您来确保该函数pure
从外部起作用 - 包括处理编译器认为它可以改变返回类型的可变性的事实一个强pure
函数,它返回一个可变类型。例如,这段代码编译得很好
char[] makeString(size_t len) pure
{
return new char[](len);
}
void main()
{
char[] a = makeString(5);
const(char)[] b = makeString(5);
const(char[]) c = makeString(5);
immutable(char)[] d = makeString(5);
immutable(char[]) e = makeString(5);
}
即使返回类型总是可变的。那是因为编译器知道它makeString
是强pure
的并返回一个无法传递给它的值 - 因此,它每次都保证是一个新值 - 因此将返回类型的可变性更改为const
orimmutable
不违反类型系统。
如果您要在其中做一些事情makeString
,涉及将函数强制转换为何pure
时违反makeString
始终返回新值的保证,那么您将破坏类型系统,并且您将面临代码非常错误的风险,具体取决于您的内容使用从返回的值进行makeString
。
pure
当你没有它时,我知道获得纯度的唯一方法是强制转换一个函数指针,这样它pure
就是它可以做到这一点,以便您完全模仿这种行为。如果您要返回immutable
数据或值类型,那会更容易,因为这样您就不会遇到编译器更改返回类型的可变性的问题,但这仍然是一件非常棘手的事情。
因此,如果您正在考虑将某些内容投射到pure
,请再想一想。是的,有可能以其他方式做不到的事情来做一些事情,但这是非常冒险的。就个人而言,我建议你决定是纯度对你更重要还是记忆对你更重要,然后你放弃另一个。其他任何事情都是高风险的。
D 允许在类型系统中表达的是一个不纯函数,它记住了一个纯函数。
从概念上讲,memoizer 也是纯粹的,但类型系统的表达能力不足以允许这样做。你需要在某个地方作弊。