D中记忆函数的纯度

时间:2013-11-10 21:44:06

标签: caching persistence d memoization purely-functional

在D?

中记忆功能时,是否有任何保存纯度的聪明方法?

我希望在缓存保存在RAM中的大型数据集的SHA1计算时使用。

2 个答案:

答案 0 :(得分:6)

简答:选择记忆或纯度。不要试着兼得。

答案很长:我不知道如何用memoization保存纯度,除非你使用强制转换来欺骗编译器并声称函数是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并返回一个无法传递给它的值 - 因此,每次都保证它是一个新值 - 因此改变可变性返回类型为immutablemakeString并未违反类型系统。

如果您要在pure内部执行某项操作,但是当makeString违反makeString始终返回新值的保证时,该功能会向pure投放功能,那么您就会破坏类型系统,根据您对pure返回的值所做的操作,您可能会冒很多错误的代码。

我知道在没有它时获得纯度的唯一方法是转换函数指针使其为immutable,但如果你这样做,那么你必须完全理解保证pure函数的作用以及编译器认为它可以用它做什么,以便您完全模仿该行为。如果您返回{{1}}数据或值类型,这会更容易,因为那时您没有编译器更改返回类型的可变性的问题,但它仍然是非常棘手的业务。

所以,如果您正考虑将某些内容投射到{{1}},请再想一想。是的,有可能做一些你不可能做到的事情,但这是非常危险的。就个人而言,我建议您决定纯度对您来说更重要,或者对您的记忆更重要,而另一方则更重要。其他任何东西都是高风险的。

答案 1 :(得分:0)

D允许在类型系统中表达的是一个不纯的函数,它会记住一个纯函数。

从概念上讲,memoizer也是纯粹的,但类型系统的表达力不足以允许。你需要在某个地方作弊。