【问题标题】:Pure functional programming in DD中的纯函数式编程
【发布时间】:2011-08-14 07:22:36
【问题描述】:

在我看来,功能纯度的强大之处在于深度代码路径可以被验证为无副作用。可以在纯说明符内的代码树规模有哪些经验,代码重用程度如何?

我发现了一些东西:

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'  

【问题讨论】:

    标签: functional-programming d side-effects


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 感谢您的 cmets。不久前我在试验时注意到纯度的弱定义,它显然非常强大,允许在纯代码中进行完全可变的 OO 编程,并且在创建惰性评估 thunk 或调度承诺等时,强形式可以很容易地被元断言对类型限定符进行编程。我认为,要让高度并发的愿景真正起飞,更多需要能够放在一个纯粹的信封内。我提到的析构函数和 postblit 问题对我影响最大,因为我需要在纯代码中引用计数,你认为它们是错误吗?
    • @John:是的,这些可能是错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 1970-01-01
    • 2010-12-23
    • 2016-04-09
    相关资源
    最近更新 更多