D中的纯函数式编程

时间:2011-04-28 00:13:55

标签: functional-programming d side-effects

在我看来,功能纯度的强大之处在于深度代码路径可以被验证为无副作用。人们在代码树规模上的经验是什么,可以在纯粹的说明符中,以及代码重用的级别是什么?

我发现了一些事情:

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'  

1 个答案:

答案 0 :(得分:21)

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

  • 标记为pure的所有函数都是纯粹的。它们可能无法访问任何全局可变状态(全局变量,线程局部变量,static变量等)或执行I / O.然而,他们可能会改变他们的论点。这些功能的关键在于它们可以从强大的纯函数中调用(详见下文),而不会违反强纯度的保证。

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

不幸的是,通用代码与pure(以及constimmutable)之间的互动相当差。有几个建议要解决这个问题,但尚未接受任何建议 \ std.algorithm被编写为尽可能通用,因此它不能要求它的lambda函数和它接受的范围是纯的。此外,在D2中添加的类型系统功能通常是语言中最多的功能,因为在修复相关问题之前已经优先考虑了更多基本功能。现在,pure基本上不可用,除了像std.math这样的小事。