定义函数式编程点

时间:2008-10-18 11:19:17

标签: functional-programming

我可以枚举函数式编程的许多功能,但是当我的朋友问我可以为我定义函数式编程吗?我不能。

8 个答案:

答案 0 :(得分:20)

我想说纯函数编程的定义点是所有计算都是在 no 副作用的函数中完成的。也就是说,函数接受输入和返回值,但不改变任何隐藏状态。在这个范例中,函数更接近地模拟他们的数学表兄弟。

当我开始使用Erlang这种具有一次写入堆栈的语言时,这对我来说已经确定了。但是,应该澄清的是,编程范例和编程语言之间存在差异。通常被称为功能的语言提供了许多鼓励或强制执行功能范例的功能(例如,Erlang具有一次写入堆栈,高阶函数,闭包等)。然而,函数式编程范例可以应用于多种语言(具有不同程度的痛苦)。

答案 1 :(得分:12)

到目前为止,许多定义都强调纯度,但有许多语言被认为是功能性的,并非纯粹的(例如,ML,Scheme)。我认为使语言“功能化”的关键属性是:

  1. 高阶函数。函数是内置数据类型,与整数和布尔值没有区别。匿名函数很容易创建和惯用(例如,lambdas)。
  2. 一切都是表达。在命令式语言中,区分变量状态和影响控制流的语句和产生值的表达式。在函数式语言(甚至是不纯的函数式语言)中,表达式求值是执行的基本单位。
  3. 鉴于这两个属性,您自然会得到我们认为具有功能的行为(例如,根据折叠和地图表示计算)。消除可变状态是使更多功能的方法。

答案 2 :(得分:8)

来自wikipedia

  

在计算机科学中,函数式编程是一种编程范式,它将计算视为数学函数的评估,并避免状态和可变数据。它强调功能的应用,与强调状态变化的命令式编程风格形成对比。

使用功能方法可带来以下好处:

  • 在函数式语言中,并发编程更容易
  • FP中的功能永远不会产生副作用 - 这使得单元测试变得更加容易。
  • 生产环境中的热门代码部署要容易得多。
  • 可以用数学方法推断功能语言。
  • 延迟评估提供了性能优化的潜力。
  • 更具表现力 - 闭包,模式匹配,高级类型系统等让程序员更容易“说出他们的意思”。
  • 简洁 - 对于某些类别的程序,功能性解决方案更加简洁。

有一篇很精彩的文章here

答案 3 :(得分:7)

能够枚举这些特征比尝试定义术语本身更有用,因为人们将在连续统一体中使用多种含义的各种语境中的“函数式编程”一词,而单个特征则单独使用更加普遍认同的更明确的定义。

以下是我想到的功能。大多数人使用术语“函数式编程”来指代这些特征​​的某些子集(最常见/最重要的是“纯度”和“高阶函数”)。

FP功能:

  • 纯度(a.k.a。不变性,避免副作用,参考透明度
  • 高阶函数(例如,将函数作为参数传递,将其作为结果返回,动态定义匿名函数作为lambda表达式)
  • 懒惰(a.k.a。非严格评估,与纯度相结合时最有用/可用)
  • 代数数据类型模式匹配
  • 闭包
  • 结束 / 部分申请
  • 参数多态(a.k.a。泛型
  • 递归(由于纯度更突出)
  • 使用表达式而不是语句进行编程(再次,来自纯度)
  • ...

您使用的上述列表中的功能越多,就越有可能标记您正在进行的“功能编程”(前两个功能 - 纯度和高阶函数 - 可能是最值得的奖励积分指向您的“FP得分”)。

答案 4 :(得分:3)

我必须补充说,函数式编程往往也会抽象你的程序和域的控制结构 - 例如,你不再在某些事物列表上做'for循环',但是你将它'映射'到某些函数产生输出。

我认为函数式编程是一种心态以及上面给出的定义。

答案 5 :(得分:1)

有两个不同的定义:

  • Chris Conway提供了较旧的定义(一流功能)。

  • John Stauffer给出了较新的定义(避免像突变这样的副作用)。这通常被称为函数式编程。

这是一个很混乱的根源......

答案 6 :(得分:-1)

这就像使用向量而不是位图来绘制图片 - 告诉画家如何更改图片而不是每一步的图片。

这是函数的应用,而不是改变状态。

答案 7 :(得分:-1)

我认为John Stauffer主要有这个定义。我还要补充一点,你需要能够传递函数。基本上你需要高阶函数,这意味着你可以轻松地传递函数(虽然传递块足够好)。

例如,非常流行的函数调用是map。它基本上等同于

list is some list of items
OutList is some empty list
foreach item in list
     OutList.append(function(item))
return OutList

使代码表示为map(函数,列表)。革命性的概念是功能是一种功能。 Javascript是具有高阶函数的语言的一个很好的例子。基本上,函数可以像变量一样对待并传递给函数或从函数返回。 C ++和C具有可以类似地使用的函数指针。 .NET委托也可以类似地使用。

然后你可以想到各种很酷的抽象......

您是否有AddItemsInList,MultiplyItemsInList等函数。?
每个函数都采用(List)并返回单个结果

您可以创建(注意,许多语言不允许您将+作为函数传递,但它似乎是表达概念的最明确方式)....

AggregateItemsInList(List, combinefunction, StepFunction)

增量函数适用于索引...更好的方法是使用下一个列表操作使它们在列表上工作,如果它存在,则使用下一个下一个下一个...

function incNormal(x) {
  return x + 1
}

function incTwo(x) {
  return x + 2
}

AggregateItemsInList(List, +, incNormal)

想要做其他所有项目吗?

AggegateItemsInList(List, +, incTwo)

想要倍增吗?

AggregateItemsInList(List, *, incNormal)

想要一起添加考试成绩吗?

function AddScores (studenta, studentb) {
   return studenta.score + studentb.score
}

AggregateItemsInList(ListOfStudents, AddScores, incOne)

高阶函数是一种非常强大的抽象。而不是必须为数字,字符串,学生等编写自定义方法。您有一个循环遍历任何事物列表的聚合方法,您只需为每种数据类型创建添加操作。