就功能编程而言,C ++能提供什么?

时间:2014-01-31 03:20:36

标签: c++ functional-programming

在C ++中,FP可能认为以下内容是固有的吗?

  • 高阶函数
  • lambdas(闭包/匿名函数)
  • 功能签名为类型
  • type polymorphism(generics)
  • 不可变数据结构
  • 代数数据类型(变体)
  • adhock数据结构(元组)
  • 部分功能应用

更新:

  • 类型推断
  • 尾递归
  • 模式匹配
  • 垃圾收集

2 个答案:

答案 0 :(得分:8)

从您的列表中,C ++可以:

  • 功能签名为类型
  • 类型多态(但不像许多函数式语言中的第一类)
  • 不可变数据结构(但它们需要更多工作)

它只能做非常有限的形式:

  • 高阶函数/闭包(基本上,没有GC,大多数更有趣的高阶函数习语都无法使用)
  • adhoc数据结构(如果您的意思是轻量级结构类型)

你基本上可以忘记:

  • 代数数据类型&模式匹配
  • 部分功能应用程序(通常需要隐式闭包)
  • 类型推断(尽管在C ++版本中人们称之为“类型推断”,但它与你用Hindley / Milner a la ML或Haskell得到的结果相差甚远)
  • 尾调用(一些编译器可以优化尾部自递归的一些有限情况,但是没有保证,并且语言对于一般情况(指向堆栈,析构函数以及所有这些)的指针是主动的。)
  • 垃圾收集(你可以使用Boehm的保守收藏家,但它不是真正的替代品,而且不太可能与第三方代码和平共存)

总的来说,尝试做一些超越琐事的功能将是C ++中的一个主要痛苦或彻底无法使用。甚至那些容易的事情往往需要如此多的样板和沉重的符号,以至于它们不是很有吸引力。 (有些C ++爱好者喜欢声称相反,但坦率地说,他们中的大多数似乎对实际的函数式编程的经验相当有限。)

答案 1 :(得分:1)

(只是为Alice的回答添加一点,非常好。)

我远不是函数式编程专家,但C ++中的编译时模板元编程语言通常被视为“功能性”,尽管它具有非常神秘的语法。在这种语言中,“函数”成为(通常是递归的)类模板实例化。部分特化用于模式匹配,终止递归等。所以编译时因子可能看起来像这样:

template <int I>
struct fact
{
    static const int value = I * fact<I-1>::value;
};

template <>
struct fact<1>
{
    static const int value = 1;
};

当然,这很可怕,但很多人(尤其是Boost开发人员)只用这些工具做了非常聪明和复杂的事情。

可能还值得一提的是C ++ 11关键字constexpr,它表示可以在编译时进行评估的函数。在C ++ 11中,constexpr函数仅限于(基本上)只是一个裸return语句;但是允许使用三元运算符和递归,因此上述编译时因子可以更简洁地(并且可以理解)重新表述为:

constexpr int fact(int i)
{
    return i == 1 ? 1 : i * fact(i-1);
}

还带来了额外的好处,即fact()现在也可以在运行时调用。这是否构成功能样式的编程留给读者决定: - )

(C ++ 14看起来可能会从constexpr函数中删除许多限制,允许在编译时调用非常大的C ++子集)