【问题标题】:Defining point of functional programming函数式编程的定义点
【发布时间】:2010-09-17 21:54:24
【问题描述】:

我可以列举函数式编程的许多特性,但是当我的朋友问我你能为我定义函数式编程吗?我做不到。

【问题讨论】:

  • 可以使用多种语言 C#、C++、Python、Perl 以函数式风格进行编程。但也有函数式语言(LISP、ML 等)。我认为从您的问题来看,我们需要关注无处不在的功能特性,而不仅仅是功能语言......
  • 这与冯诺依曼和丘奇的 Lambda 有关

标签: functional-programming


【解决方案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(function, list)。革命性的概念是功能就是功能。 Javascript 是具有高阶函数的语言的一个很好的例子。基本上,函数可以被视为变量并传递给函数或从函数返回。 C++ 和 C 具有可以类似使用的函数指针。 .NET 委托也可以类似地使用。

那么你可以想出各种很酷的抽象......

你有 AddItemsInList、MultiplyItemsInList 等函数吗?
每个函数接受 (List) 并返回单个结果

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

AggregateItemsInList(List, combinefunction, StepFunction)

增量函数适用于索引...更好的是使用列表操作(如 next 和 for incTwo next 如果存在)使它们适用于列表...

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)

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

【讨论】:

    【解决方案2】:

    有两个不同的定义:

    • Chris Conway 给出了较早的定义(一等函数)。

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

    这是很多混乱的根源......

    【讨论】:

      【解决方案3】:

      能够列举特征比试图定义术语本身更有用,因为人们将在各种上下文中使用“函数式编程”一词,在一个连续统一体中具有多种含义,而各个特征分别具有更清晰的定义,得到更普遍的认同。

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

      FP 功能:

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

      您使用的上述列表中的功能越多,就越有可能有人将您正在做的事情标记为“函数式编程”(前两个功能 - 纯函数和高阶函数 - 可能最值得额外对您的“FP 分数”的奖励积分)。

      【讨论】:

        【解决方案4】:

        来自wikipedia

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

        使用函数式方法有以下好处:

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

        有一篇很棒的文章更详细here

        【讨论】:

        • 您忘记了 FP 的“无副作用”核心方面带来的 2 个重要好处:记忆和并行化变得几乎微不足道,因此 FP 项目可以达到令人印象深刻的速度(如果我没记错的话,谷歌搜索由于这些原因,使用 FP 实现)
        • 琐事 - 错字:'FP 中的函数可能会导致副作用'应该用'never'代替'ever',我相信。
        【解决方案5】:

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

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

        【讨论】:

        • 我要补充一点,您可以在许多常见的编程语言中执行此操作,而不是使用 ErLang/其他函数式语言。但简而言之,这就是定义。
        • 不正确。您指的是 FP。有些 FP 并非没有副作用。你是conflating the taxonomy of FP vs. procedural, with IP vs. DP
        • @ShelbyMooreIII 许多人(包括我自己)会认为函数式编程是声明式编程的子集。您链接的问题中得票最高的答案如此说明。如果您将函数式编程视为“使用数学函数进行编程”,那么函数式编程确实是声明性的,因为数学函数不会产生副作用。如果您将“函数式编程”视为“函数式编程”,那么恕我直言,这并不意味着太多。
        【解决方案6】:

        到目前为止,许多定义都强调了纯粹性,但是有许多被认为是函数式的语言根本不是纯粹的(例如,ML、Scheme)。我认为使语言“功能化”的关键属性是:

        1. 高阶函数。函数是一种内置数据类型,与整数和布尔值没有什么不同。匿名函数易于创建和惯用(例如 lambda)。
        2. 一切都是一种表达。在命令式语言中,语句(改变状态并影响控制流)和表达式(产生值)之间存在区别。在函数式语言(甚至是非纯函数式语言)中,表达式求值是执行的基本单元。

        鉴于这两个属性,您自然会得到我们认为是函数式的行为(例如,用折叠和映射表示计算)。消除可变状态是使事物更加功能化的一种方式。

        【讨论】:

        • 我反对 2,因为问题是关于函数编程的。你可以在 Python/Perl 中做到这一点。语言是必须的。但是有了 map/filter/lamda/passing 函数,你可以用函数式编程。
        • if-then-else 是一个不好的例子,因为大多数语言都有“条件表达式”。 Python 和 Perl 在语句和表达式之间肯定有区别
        【解决方案7】:

        我必须补充一点,函数式编程也倾向于抽象程序和域的控制结构 - 例如,您不再对某些事物列表执行“for循环”,而是将其与某些事物“映射”产生输出的函数。

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

        【讨论】:

          【解决方案8】:

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

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

          【讨论】:

            猜你喜欢
            • 2012-11-07
            • 2014-06-14
            • 2021-12-08
            • 2010-09-06
            • 2014-12-18
            • 2015-07-23
            • 1970-01-01
            • 2011-01-18
            相关资源
            最近更新 更多