首页 文章

D中的纯函数式编程

提问于
浏览
22

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

我发现的一些事情:

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 回答

  • 21

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

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

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

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

相关问题