函数式编程( Functional)与命令式编程( Imperative)对比
1.函数式编程带来的好处
函数式编程近些年异军突起,又重新回到了人们的视线,并得到蓬勃发展。总结起来,无外乎如下好处:
1.减少了可变量(Immutable Variable)的声明,程序更为安全。
2.相比命令式编程,少了非常多的状态变量的声明与维护,天然适合高并发多现成并行计算等任务,这也是函数是编程近年又大热的重要原因。
3.代码更为简洁,可读性更强,对强迫症的同学来说是个重大福音。
2.函数式编程的本质
函数式编程中的函数这个术语不是指计算机中的函数(实际上是Subroutine),而是指数学中的函数,即自变量的映射。也就是说一个函数的值仅决定于函数参数的值,不依赖其他状态。比如sqrt(x)函数计算x的平方根,只要x不变,不论什么时候调用,调用几次,值都是不变的。
引用知乎上的一段描述:
纯函数式编程语言中的变量也不是命令式编程语言中的变量,即存储状态的单元,而是代数中的变量,即一个值的名称。变量的值是不可变的(immutable),也就是说不允许像命令式编程语言中那样多次给一个变量赋值。比如说在命令式编程语言我们写“x = x + 1”,这依赖可变状态的事实,拿给程序员看说是对的,但拿给数学家看,却被认为这个等式为假。
函数式语言的如条件语句,循环语句也不是命令式编程语言中的控制语句,而是函数的语法糖,比如在Scala语言中,if else不是语句而是三元运算符,是有返回值的。
3.实例
1.集合中包含某一个元素
经常有判断集合是否包含某一元素的需求。在命令式编程中,我们一般都会这么干:
public class IfExists {
public static void traditional() {
boolean flag = false;
String[] citys = {"bj","sh","gz","sz"};
for(String city:citys) {
if(city.equals("bj")) {
flag = true;
break;
}
}
System.out.println(flag);
}
public static void main(String[] args) {
traditional();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
这段代码正常工作肯定是没有问题的。而且逻辑本身也很简单,大家都能写出来。但是在我看来,是不是太长了。。。
看看我们用scala实现一下
object IfExists{
def main(args: Array[String]): Unit = {
println(Array("bj","sh","gz","sz").contains("bj"))
}
}
- 1
- 2
- 3
- 4
- 5
- 6
直接针对集合进行操作,省去了讨厌的循环判断等一系列对我们来说累赘得很的操作。瞬间感觉清爽好多有木有。
2.对一个集合做一系列处理
现在有个价格的集合。如果价格大于20,先九折,然后相加。如果用java实现
public class Price {
public final static List<BigDecimal> prices = Arrays.asList(
new BigDecimal("10"), new BigDecimal("30"), new BigDecimal("17"),
new BigDecimal("20"), new BigDecimal("15"), new BigDecimal("18"),
new BigDecimal("45"), new BigDecimal("12"));
public static void sumOfPrices() {
BigDecimal total = BigDecimal.ZERO;
for(BigDecimal price:prices) {
if(price.compareTo(BigDecimal.valueOf(20)) > 0) {
total = total.add(price.multiply(BigDecimal.valueOf(0.9)));
}
}
System.out.println("The total is: " + total);
}
public static void main(String[] args) {
sumOfPrices();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
这代码也可以正常工作没有问题。问题跟前面一样,还是太累赘,不是那么优雅,可读性也不是很好。用scala写一下上面的逻辑:
object Prices {
def main(args: Array[String]): Unit = {
val prices = Array(10, 30, 17, 20, 15, 18, 45, 12)
val total = prices.filter(x => x>20)
.map(x => x*0.9)
.reduce((x,y) => x+y)
println("total is: " + total)
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
简直就是强迫症患者的福音有木有!而且这段代码的可读性不知道高了多少:针对集合,先做filter操作,将大于20的元素选出来,然后做map操作,乘以0.9的系数,最后再将所有的值相加。接近于自然语言的表达方式,一目了然。
函数式编程( Functional)与命令式编程( Imperative)对比的更多相关文章
- 编程范式:命令式编程(Imperative)、声明式编程(Declarative)和函数式编程(Functional)
主要的编程范式有三种:命令式编程,声明式编程和函数式编程. 命令式编程: 命令式编程的主要思想是关注计算机执行的步骤,即一步一步告诉计算机先做什么再做什么. 比如:如果你想在一个数字集合 collec ...
- Python - 命令式编程与符号编程
原文链接:https://zh.d2l.ai/chapter_computational-performance/hybridize.html本文是对原文内容的摘取和扩展. 命令式编程(imperat ...
- 『MXNet』第六弹_Gluon性能提升 静态图 动态图 符号式编程 命令式编程
https://www.cnblogs.com/hellcat/p/9084894.html 目录 一.符号式编程 1.命令式编程和符号式编程 2.MXNet的符号式编程 二.惰性计算 用同步函数实际 ...
- Atitit 函数式编程与命令式编程的区别attilax总结 qbf
Atitit 函数式编程与命令式编程的区别attilax总结 qbf 1.1. 函数式程序就是一个表达式.命令式程序就是一个冯诺依曼机的指令序列. 命令式编程是面向计算机硬件的抽象,有变量(对应着存 ...
- 关于函数式编程(Functional Programming)
初学函数式编程,相信很多程序员兄弟们对于这个名字熟悉又陌生.函数,对于程序员来说并不陌生,编程对于程序员来说也并不陌生,但是函数式编程语言(Functional Programming languag ...
- 函数式编程 - Functional Programming
什么是函数式编程 函数式编程是一种编程范式. 编程范式又是什么? 编程范式是一种解决问题的思路. 命令式编程 把程序看作 一系列改变状态的指令: 函数式编程 把程序看作 一系列数学函数映射的组合. i ...
- Java中的函数式编程(二)函数式接口Functional Interface
写在前面 前面说过,判断一门语言是否支持函数式编程,一个重要的判断标准就是:它是否将函数看做是"第一等公民(first-class citizens)".函数是"第一等公 ...
- 面向函数范式编程(Functional programming)
函数编程(简称FP)不只代指Haskell Scala等之类的语言,还表示一种编程思维,软件思考方式,也称面向函数编程. 编程的本质是组合,组合的本质是范畴Category,而范畴是函数的组合. 首先 ...
- 命令式编程 vs 声明式编程
实际上我们绝大多数程序员都是在用命令式风格在编程, 这是和我们的冯诺依曼计算机机构密切相关的. (码农翻身注: 参见文章<冯诺依曼计算机的诞生>) 在一个冯诺依曼计算机中, 最核心的就是C ...
随机推荐
- hdu5443 The Water Problem
The Water Problem Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- DS-博客作业06--图
DS-博客作业06--图 1.本周学习总结(0--2分) 1.思维导图 2.谈谈你对图结构的认识及学习体会. 本章的图,因为和上一章的树上的比较紧凑,所以在考前一个星期也有看书背代码,也有理解代码和思 ...
- 【bzoj2338】[HNOI2011]数矩形 计算几何
题目描述 题解 计算几何 由于对角线平分且相等的四边形是矩形,因此我们可以把每条对角线存起来,按照对角线长度和中点位置为关键字排序,这样对于每个相同长度和中点的对角线就排到了一起. 于是对于每段可能形 ...
- 【Luogu】P2604网络扩容(费用流乱搞)
题目链接 这题比较水,就是乱改改费用流模板.判断一下已经满流的边和没有满流的边,然后再改改最大流模板,然后把它们拼起来就是了. 话说这题第一遍90,然后撕烤一会发现自己yy的spfa扩容方式不允许反悔 ...
- HDU——1020Encoding(水题,string过)
Encoding Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- 学习struts2及MVC
1.MVC模式基础 1.1.MVC模式简介 MVC是一种架构型模式,它本身并不引入新的功能,只是用来指导我们改善应用程序的架构,使得应用的模型和视图相分离,从而达到更好的开发和维护效率.在MVC模式中 ...
- [转] Makefile 基础 (9) —— Makefile 使用make更新函数库文件
该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客:(最原始版本) http://blog.csdn.net/haoel/article/details/2886 我转自 ...
- mybatis如何传入一个list参数
<!-- 7.2 foreach(循环List<String>参数) - 作为where中in的条件 --> <select id="getStudentLi ...
- 标准C程序设计七---33
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- 52深入理解C指针之---不透明指针
该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教.一.size_t:用于安全表示长度,所有平台和系统都会解析成自己对应的长度 1.定义:s ...