函数式编程 函子,子程序和函数

  函数式编程 函子,子程序和函数

  通用编程语言包含两个基本抽象:

过程抽象

数据抽象

。过程抽象有时被称为

控制抽象

  子程序是在1950年之前发明的,当时还没有完全被接受为一种抽象。相反,起初它被视为一种保存代码的机制,但很快子程序就被认为是一种进程抽象的方式。认识到子例程可以作为抽象机制使用会产生三个重要的结果。

  人们发明了一些语言,支持各种参数传递机制,奠定了“结构化编程”的基础。语言开始支持嵌套的子程序(比如JS的function,Java的inner class),催生了“结构化编程”,为尝试构建大型系统提供了指导,将子程序作为基本的积木。

  

子程序

是最重要的进程抽象机制。面向对象语言中的

方法

非常类似于子程序的概念,但区别在于它们的调用以及与类或对象关联的方式。

  

一、子程序的特征

每个子程序在执行过程中只有一个入口,调用程序单元停止执行,即任何时刻子程序执行完毕后,总是只有一个子程序将控制权返回给调用程序。注意:

协同程序

并发程序

的特性与子程序的特性不同。

  

二、两种类型的子程序

子程序分为过程和函数两种。

  

过程

是定义参数化技术的一系列语句。这些计算由一条call语句开始。该过程实际上定义了一条新语句。在Ada中,过程被称为过程,但在Fortran中,过程被称为子例程。

  

函数

在结构上模仿过程,但在语义上模仿数学中的功能。如果是纯功能,不会有副作用。

  注意:有些编程语义既提供过程又提供函数,比如Fortain和Ada;例如,一些基于C的语言只有函数。然而,C中函数的行为类似于过程的行为。还可以定义这些函数不返回值,只要它们的返回类型定义为void。Java/C /C#也类似。

  

三、子程序的首部定义

表明它是一种特殊类型子程序的定义(有些语言既包括过程又包括函数)。子程序的类型通常由一个特殊的字头指定,它给子程序一个名称。标题可以解释一系列参数(可选)。

  比如定义一个sum的子程序。

  FORTRAN语言

  子程序sum(参数)Ada

  过程总和(参数)Python

  定义总和(参数)C/C /Java

  int sum(参数)JavaScript

  函数和(参数)

  Ruby/JavaScript函数和上面的有一些有趣的区别。它可以在类定义时定义,也可以在类外定义。在类之外定义的方法被认为是调用对象或根对象。如果return语句后没有表达式,Ruby返回nil,如果没有返回,JavaScript返回undefined。

  

四、参数

子程序通常描述计算,它以两种方式处理数据:

  如前所述,纯函数只能通过直接访问非局部变量的参数传递来计算。非纯函数有副作用。参数分为形式参数和实际参数。

  

形参

:子程序头中定义的参数称为形参,也称为

虚变量

。因为它不是普通意义上的变量,所以只有在调用子程序的时候才会绑定到存储空间。

  

实参

:子例程调用语句包括子例程的名称和一组绑定子例程参数的参数。这些参数称为自变量。

  大部分语言的实参参数的绑定(关联)都是基于

位置

。也就是说,第一个参数对应于第一个参数,第二个参数对应于第二个参数。诸如此类。例如JavaScript代码

  函数sum(a,b){ return a b;}sum(3,5);函数sum定义了两个参数a和B.调用时,对应的参数是3,5。

  使用位置来关联真实的参与参数是一种非常有效和安全的方法。但当参数较多时(比如形参表中有10个以上的参数),程序员在调用子程序时很容易犯参数顺序错误。因此,一些语言引入了称为关键字参数的解决方案。

  

关键字参数

的含义是将形参名称和实参一起声明。也就是声明的时候和参数一一对应。它的优点是可以以任意顺序出现在参数表中。比如Python代码

  DEF SUM (len=mylen,list=mylist,result=myresult)定义函数时将参数与变量一一对应。使用关键字参数的缺点是子程序必须知道参数的名称。

  

参数默认值

在Python、Ruby、C、Fortran 95、Ada和PHP中,形参可以有默认值。如果参数没有传递给子例程的参数,将使用默认值。比如Python

  DEF (a=5): print (a) show()定义函数show的参数A的默认值为5。如果调用show时没有传递参数,那么默认情况下将打印5。

  

:JavaScript之父Brendan Eich将在语言中加入这一特性。Javascript中的函数定义可能采用以下形式:

  fun(x=5,y=10){ }

  在大多数语言中,形参没有默认值,调用时实参的个数必须与形参相匹配。但在C,C,Perl和JavaScript中,没有这样的要求。虽然允许参数个数不同的设计容易产生误差,但有时也很灵活方便。例如,C的printf函数可以打印任意数量的项目。JavaScript还可以根据参数的个数来模拟函数的重载。

  相关:

  JavaScript-ecmascript-harmony-spider monkey-spider node-V8-V8 monkey-nodejs-node conf/

  JavaScript-ecmascript-和谐-咖啡脚本/

函数式编程 函子,子程序和函数