23

在我看来,功能纯度的力量在于可以验证深层代码路径无副作用。人们对可以在纯说明符内的代码树的规模有什么经验,代码重用的水平如何?

我发现了几件事:

std.algorithm大多数情况下没有标记为pure,但可能在很大程度上是纯的,或者通过要求实例化函数或 mixin 纯度的纯算法版本,或者纯度说明符本身是静态多态的。
像这样有用的转换器to!string( someInt )目前并不纯。

用户定义的结构似乎有问题(如下图所示):
1. 嵌套结构上的纯析构函数
2. 即使在非嵌套结构上也有纯 postblit 函数

以下代码目前在 DMD 2.052 win 32-bit 上给出了多个错误

struct InnerStruct
{
    pure this(this) {}
    pure ~this() {}
}

struct OuterStruct
{
    InnerStruct innerStruct;
    pure this(this) {}
    pure ~this() {}
}

pure void somePureFunc()
{
    OuterStruct s1 = OuterStruct(); // pure nested destructor does not compile
    OuterStruct s2 = s1;
    InnerStruct is1 = InnerStruct(); // pure non-nested destructor seems to compile
    InnerStruct is2 = is1; // pure non-nested postblit does not compile
}

void main()
{
    somePureFunc();
}
pure_postblit.d(18): Error: pure function 'somePureFunc' cannot call impure function '__cpctor'  
pure_postblit.d(20): Error: pure function 'somePureFunc' cannot call impure function '__cpctor'  
pure_postblit.d(18): Error: pure function 'somePureFunc' cannot call impure function '~this'  
pure_postblit.d(17): Error: pure function 'somePureFunc' cannot call impure function '~this'  
4

1 回答 1

22

理论上pure,D 中的要点是它应该允许保证一个函数是无副作用的,而不管该函数是如何实现的。D中有两种纯度:

  • 所有标记的函数pure都是弱纯的。它们可能无法访问任何全局可变状态(全局变量、线程局部变量、static变量等)或执行 I/O。然而,他们可能会改变他们的论点。这些函数的要点是它们可以从强纯函数(下面详述)调用而不会违反强纯的保证。

  • 所有弱纯函数并且没有任何可变间接参数的函数都是强纯函数。和类型构造函数可以用来保证这一点constimmutable(在处理结构和类时,this指针被认为是一个参数。)强纯函数具有函数式编程人们谈论的所有好的属性,即使它们是使用可变状态实现的。对于任何给定的参数,强纯函数总是返回相同的值,并且没有可观察到的副作用。强纯函数是引用透明的,这意味着它们的返回值可以用给定的一组参数代替对它们的调用,而不会影响可观察的行为。任何强纯函数都可以与任何其他强纯函数安全地并行执行。

pure不幸的是,通用代码和(以及const和)之间的交互immutable很差。有几个建议来解决这个问题,但还没有被接受。
\std.algorithm 被编写为尽可能通用,因此它不能要求它的 lambda 函数和它接受的范围是纯的。此外,在 D2 中添加的类型系统特性通常是该语言中最容易出错的特性,因为在修复相关问题之前,更基本的事情已被优先考虑。现在,pure除了像 std.math 这样的琐碎情况外,基本上不可用。

于 2011-04-28T03:05:32.677 回答