函数式编程介绍

本文将描述函数式编程的基本理论,从而让你理解什么是函数式编程,同时也会展示“函数式编程”和“面向对象”这两种不同风格的编程范式之间的区别。本文是函数式编程系列的入门篇,后续文章陆续会发出。

什么是函数

函数式编程背后的理论依据是数学,数学函数背后有一系列有意思的特点,而函数式编程语言则试图模拟这些特性。
让我们先来看一个简单的数学函数:

y =  x + 1

这个数学函数的意图是显而易见的,给定一个变量x然后返回x + 1, 上面的数学函数用C#来表示:

public int Add1(int x)
{
    return x + 1;
}

数学函数跟我们用命令式语言编写的函数相比有两个明显的区别:

  • 同一个输入在数学函数里总能得到相同的返回值
  • 数学函数没有副作用
  • 输入值和输出值是不变的(immutable)

这三个区别具体是什么意思呢?

同一个输入在数学函数里总能得到相同的返回值

在命令式语言(imperative programming)中,我们总是在函数内部做一些计算和处理,然后返回最终结果。在数学函数中没有计算和处理,你可以认为数学函数的返回值是对输入值的一一映射。上面提到的数学函数极端定义如下:

int Add1(int x)
{
   switch (x)
   {
   case 0: return 1;
   case 1: return 2;
   case 2: return 3;
   case 3: return 4;
   //...
   }
}

当然现实环境中我们不会写出这样的代码,但是数学函数的思想是类似的,里面没有对事情的处理逻辑。
关于命令式语言和声明式语言的区别看这里:命令式语言和声明式语言的区别

数学函数没有副作用

数学函数所做的事就是根据每一个输入返回不同的输出,整个过程没有对输入值做任何改变,在返回输出的过程中也没有对其他的任何环境造成影响,在函数式语言里这样的函数被称为纯函数

输入值和输出值是不变的

immutable使得代码更加具有预测性,考虑下面的代码:

public int Add1(int x)
{
    x = 2;
    return x + 1;
}

public void InvokeAdd1()
{
    var x = 10;
    var y = Add1(x);

    Console.WriteLine($"x={x}, y={y}");
}

你试图在Add1函数中实现y = x + 1,但是由于失误将x的值改为了2,从而导致了一个bug,immutable则强制你无法修改x的值,一旦初始化就不能再修改。显然C#默认是mutable的,但在常见的函数式语言中,变量声明式immutable的,比如在F#中将x初始化为6然后再修改为7会编译出错:

let x = 6
x <- 7

作为一个修炼命令式语言多年的开发者也许会内心充满疑问,无法修改变量真的靠谱?答案是肯定的,在后面的文章中将会展示这种用法。

纯函数带来的好处

看似不起眼的三个特点实际上会带来非常强大的益处,所以函数式编程语言则试图把这三个特性带到他们的设计当中。

得益于纯函数的这种特点,对同一个输入无论你重复调用多次,都会返回同样的结果,并且没有副作用,因此:

  • 所有的调用可以使并行的。 加入你想用1到10000之间的数字去调用Add1函数,你可以把这些计算过程分配到10个不同的CPU上并行执行,由于所有的调用都是没有副作用的,所以你不需要使用命令式语言中的锁机制就能完成任务;
  • 懒加载成为现实,你可以在真正需要结果的时候去执行计算,因为你可以保证在任何时刻对同一个输入返回的结果总是相同的
  • 你可以对函数的计算结果进行缓存,因为相同的输入总能得到相同的结果,所以可以轻而易举的对函数增减缓存功能

后续文章即将发出,请想了解函数式编程的童鞋支持并关注。

原文地址:https://www.cnblogs.com/xiandnc/p/9256503.html

时间: 2024-11-10 05:29:01

函数式编程介绍的相关文章

Python学习笔记八:文件操作(续),文件编码与解码,函数,递归,函数式编程介绍,高阶函数

文件操作(续) 获得文件句柄位置,f.tell(),从0开始,按字符数计数 f.read(5),读取5个字符 返回文件句柄到某位置,f.seek(0) 文件在编辑过程中改变编码,f.detech() 获取文件编码,f.encoding() 获取文件在内存中的编号,f.fileno() 获取文件终端类型(tty.打印机等),f.isatty() 获取文件名,f.name() 判断文件句柄是否可移动(tty等不可移动),f.seekable() 判断文件是否可读,f.readable() 判断文件是

Python学习之路:函数式编程介绍&amp;高阶函数

函数式编程:一种抽象程度很高的范式,重要特点:输入是确定的,输出就是确定的: Python对函数式编程,部分支持: 高阶函数: def add(x,y,f):#函数本身传给函数,就是高阶函数 return f(x)+f(y) res = add(3,-6,abs) print(res)

python基础13函数以及函数式编程

主要内容 函数基本语法及特性 参数与局部变 返回值 4.递归 名函数 6.函数式编程介绍 阶函数 8.内置函数 函数基本语法及特性 定义 数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一 个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变 量,y是x的函数.自变量x的取值范围叫做这个函数的定义域. 但编程中的「函数」概念,与数学中的函数是有很 同的 函数是逻辑结构化和过程化的一种编程方法 函数的优点 减少重复代码 使程序变的可扩展 使程序

函数与函数式编程

函数与函数式编程 介绍 在过去的十年间,大家广为熟知的编程方法无非两种:面向对象和面向过程,其实,无论哪种,都是一种编程的规范或者是如何编程的方法论.而如今,一种更为古老的编程方式:函数式编程,以其不保存状态,不修改变量等特性重新进入人们的视野.下面我们就来依次了解这一传统的编程理念,让我们从基本的函数概念开始. 函数定义: 初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变量,y是x的

scala函数式编程(二) scala基础语法介绍

上次我们介绍了函数式编程的好处,并使用scala写了一个小小的例子帮助大家理解,从这里开始我将真正开始介绍scala编程的一些内容. 这里会先重点介绍scala的一些语法.当然,这里是假设你有一些java或者python的基础,毕竟大部分人不会将scala当作第一门学习编程的语言. 不过这些语法知识记不住也没关系,本身语法这种东西就应该在使用中被记住.这里写这篇的目的也只是梳理一遍,方便大家对语法有个初步的印象,后面可以随时查询. PS:所使用的版本是scala 2.11.8,那我们开始吧 一.

javascript函数式编程简单介绍

函数式编程在前端已经成为了一个热门的话题,近几年很多的应用程序代码库里大量使用着函数式编程思想.这里对JavaSctipt中的函数式编程做一个简单介绍. 什么是函数式编程 函数式编程是一种编程范式,主要是利用函数把运算过程封装起来,通过组合各种函数来计算结果.函数式编程意味着开发者可以在更短的时间内编写具有更少错误的代码. 函数式编程的简单例子 假设要把一个字符串转换成每个单词首字母大写,可以这样来实现: var string = 'i do like yanggb'; var result =

javaScript函数式编程-包含闭包、链式优化及柯里化

本文着重介绍个人理解的函数式编程. 函数式编程个人理解为:以函数为主要载体的编程方式. 好处: 语义更加清晰 可复用性高 可维护性好 作用域局限.副作用少 基本函数式编程: //实现数组中每个单词首字母大写 //一般写法 const arr = ['apple','orange','pear']; for(const i in arr) { const c = arr[i][0]; arr[i] = c.toUpperCase() + arr[i].slice(1); //slice()从已有的

[原创译书] JS函数式编程 前言

前言 函数式编程是一种能够让你编写更聪明的代码的方式,可以减低复杂度,增强模块化. 它是一种通过灵巧地变化.组合.使用函数达到编写简洁代码的方式. Javascript提供了一个实现这些的超赞的途径.Javascript,这个Internet的脚本语言, 它的核心实际上是一个函数式语言.通过学习如何显露出它作为一个函数式语言的真实身份, 我们可以实现强大的.更易维护的以及更可靠的web应用. 通过这些,Javascript的那些怪癖和缺陷将会立刻变得清晰,并且语言本身也将会无限精彩. 学习如何使

[转] 函数式编程初探

诞生50多年之后,函数式编程(functional programming)开始获得越来越多的关注. 不仅最古老的函数式语言Lisp重获青春,而且新的函数式语言层出不穷,比如Erlang.clojure.Scala.F#等等.目前最当红的Python.Ruby.Javascript,对函数式编程的支持都很强,就连老牌的面向对象的Java.面向过程的PHP,都忙不迭地加入对匿名函数的支持.越来越多的迹象表明,函数式编程已经不再是学术界的最爱,开始大踏步地在业界投入实用. 也许继"面向对象编程&qu