D中记忆函数的纯度

Nor*_*löw 6 persistence caching d memoization purely-functional

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

在缓存保存在RAM中的大型数据集的SHA1计算时,我想要这个.

Jon*_*vis 6

简短回答:选择记忆或纯度.不要试着兼顾两者.

答案长:我不知道如何用memoization来保持纯度,除非你使用强制转换来欺骗编译器并声称函数pure不是时,因为为了记忆,你必须存储参数和结果打破了纯度,因为pure函数的第一个保证是它们不访问可变的全局变量或静态变量(这是你能够记住任何东西的唯一方法).

所以,如果你做了类似的事情

alias pure nothrow Foo function() FuncType;
auto result = (cast(FuncType)&theFunc)();
Run Code Online (Sandbox Code Playgroud)

然后你就可以把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);
}
Run Code Online (Sandbox Code Playgroud)

即使返回类型总是可变的.那是因为编译器知道makeString强大pure并且返回一个无法传递给它的值 - 因此,每次都保证它是一个新值 - 因此改变返回类型的可变性为constimmutable不违反类型系统.

如果你在内部做了一些事情,makeString那就是pure当它违反了makeString总是返回一个新值的保证时,就会抛出一个函数,那么你就会破坏类型系统,并且你冒着错误代码的风险取决于你做了返回的值makeString.

当你没有它时,我知道获得纯度的唯一方法是转换一个函数指针pure,但是如果你这样做,那么你必须完全理解pure函数的保证和编译器的认为它可以做到这一点,以便你完全模仿这种行为.如果你返回immutable数据或值类型,这会更容易,因为那时你没有编译器改变返回类型的可变性的问题,但它仍然是非常棘手的业务.

所以,如果你想要投入一些东西,那就pure再想一想.是的,有可能做一些你不可能做到的事情,但这是非常危险的.就个人而言,我建议您决定纯度对您来说更重要,或者对您的记忆更重要,并且您放弃另一个.其他任何东西都是高风险的.

  • @Nordlöw无论是否在TLS中都与纯度无关.当然,如果不是这样,那么当你做一些像纯函数一样的事情时,你会遇到更多的问题,但问题是你被迫将函数转换为纯函数来进行memoization,那就是开辟了一大堆蠕虫.如果你这样做,你必须以一种完全模仿系统类型系统所需要的方式来做,并且不违反任何保证或搞乱任何优化.这需要你非常了解并且非常小心.我建议不要尝试. (2认同)