编程范式巡礼第一季 三大基石

最近迷上了一些哲史类书籍,回望过去、放眼未来,往往沉浸在其思维之美中无法自拔。计算机编程是一门非常年轻的学科,沉淀不足也是年轻的一个侧面,在编程领域,有足够思想深度的作品并不多。这本书的作者老冒我觉得就是一个有深度的人。这周开始,给大家讲一下他的好书《冒号课堂》。

编程范式是什么?

在年底的各大媒体的展望中,我发现编程能力已经悄悄然占据了比较重要的位置,被认为是一种影响未来的能力。编程从宏观上讲就是操作计算机工作的方法,而从微观上讲是寻求一种机制,将指定的输入转换为指定的输出。

但是为什么编程能力是难练成的呢?我觉得最大的问题大于人和计算机的思维方式是不同的,人的思维追求简单,而计算机的思维追求复杂。在这之间有一个巨大的鸿沟,其难点是使用人的思维来翻译计算机思维。

编程范式就是这种翻译方法,它是程序王国的世界观和方法论,也许是破解编程这门学科的钥匙。

命令范式

我们需要从最古老的范式开始,也是编程世界的第一性原理。

其世界观是:程序是由若干行动指令组成的有序列表。其方法论是:用变量来存储数据,用语句来执行指令。

这个是由目前计算机的起源,也就是冯·诺依曼机的设计来决定的,也是所有计算机技术的基础。机器语言就是这样设计的,也就是说这是计算机唯一可以直接理解的东西。

那是不是可以有其他的机器语言呢?理论上当然是可以的,在早期也是存在的,但是都未有流行。在命令范式中有一个非常重要的推论:

任何程序都可以用顺序、选择和循环3种基本控制结构来表示。

这也是我们目前绝大多数语言的实现方式,是日常最为常见的编程方法。下面是一个范例:

function getData(col){
var results=[];
for(var i =0; i < n ; i++){
if(col[i]&&col[i].data){
results.push(col[i].data);
}
}
return results;
}

大家可以试一下用语言把这段代码进行一下解释,我也找不少同事做过实验,就算是资深程序员解读的也不完全相同,这也说明了命令范式和人的思维方式有所不同,会不太容易理解,如何解决,就需要新的范式了。

函数范式

上面的那段代码,到底是哪里不容易理解?应该来说是细节的描述过多,因为人的思维喜欢简单,而细节是复杂的。所以我们需要一种不一样的描述方法。

命令式编程是行动导向的,算法是显性而目标是隐性的;声明式编程是目标驱动的,目前是显性而算法是隐性的。

命令式编程有几种不同的流派,其中函数范式是现在最为流行的。

在函数范式中,函数是程序的核心,是头等公民。

这个说法还是过于抽象,我们从上面的例子出发。这段代码中,最让人难以理解的应该是for..下面的这段内容,也就是循环段落。在命令范式的三大结构中,我们会发现唯有循环结构是人在日常表达中不会使用的,这也是计算机复杂性的最重要表现。在声明式编程的世界观里,我们就需要把这段代码藏起来。

但是如果只是采用命令范式中"语句+变量"的表达方式,大概能改进成如下代码,是好了一点,但是还是挺让人费解的。

function getData(col){
var results=[];
doSelect();
return results;
} function doSelect(){
results = loop(
f-> { if(col[i]&&col[i].data){
results.push(col[i].data);
}});
}
}

这个时候,我们就需要对范式进行一下改进了。其实只是一个小改动,扩展一下"变量"的语义:

语句+变量 --> 语句+变量/函数

我想这个也是函数范式名称的由来,这么做的效果立竿见影,"变量"复杂了,那么"语句"就能变的简单而且通用。我们可以把上面这段代码改进为如下:

function getData(col){
return col
.filter(item=>item&&item.data)
.map(item=>item.data);
}

是不是可读性一下子强了很多,改变只是源于一个小小的思维上的转变。以此为基础,发展出了许许多多强大的方法和工具,给码农们提供了强大的支持。读到这里,我其实是有点感动的,这就是思维的力量。

对象范式

让我们继续,函数范式把程序的可理解性提升了一截,那思维探索就停止了么,当然不会。

命令范式的代码在理解性方面还有其他的问题么?有!

和日常的语言相比,程序的表示总是让人觉得有些别扭。以第一行代码为例。

   function getData(col)

我们直接读是"获取数据 列",挺奇怪的吧。举一个日常表达的例子会更形象点,程序的表达类似这样:

吃 牛 草

看出问题了吧,就是缺少主语。我们日常的表达中,主语是个不可缺少的内容,但是在计算机语言中偏偏就没有。那这句话如何表达才能清晰呢,挺简单的,换下顺序增加主语就可以。

牛 吃 草

在程序世界里,给主语起了个名字,叫Object,基于此,诞生了对象范式。这里有一个非常混淆的地方,就是Object并不是主语的意思,而且意思恰恰相反。我觉得这也是对象范式这个概念,始终让大家非常困惑的一个原因。这里只是给一个简单化的理解方法。

语言表达的改进,带来的不仅仅是理解的提升,更大的改变是可以将我们理解正常世界的方法用在理解计算机世界之上,这个化学反应是巨大的。这里举一个简单的例子,就是信息压缩。

牛 吃 草

牛 喝 水

这两句话,我们自然会想到一个压缩的方法:

牛 {
吃();
喝水();
}

进一步,又出现了一种新动物,我们又会想到一种压缩:

羊 {
吃();
喝水();
}
-->
哺乳动物 {
吃();
喝水();
}

这就是OO中的封装和继承的由来,追求的是简单,源于日常理解世界的方法。为什么现在对象范式这么流行,我觉得重要的原因是其更符合日常思维,更具有易用性。

小结

今天主要是介绍了《冒号课堂》中讲到的最为基础的三个范式,从一个小小的改动开始,撬动了一个大大的世界,编程领域博大精深,这只是入门,后面还有更好玩、更有趣的范式等着我们,下次再继续探索。

前几天听到Google的人工智能专家李飞飞的演讲,讲到传统的学习,是用人认识知识,然后再让机器学习,但是机器学习不一样,是把认知知识这一层省掉了,直接让机器进行学习。这是一种思维上的大跃进,说实话我还不能完全理解,但有点可以确定的是,思维上的提升已经刻不容缓,加油。

小课堂week16 编程范式巡礼第一季 三大基石的更多相关文章

  1. 小课堂week19 编程范式巡礼最终季 超级范式

    编程范式巡礼(最终季)--超级范式 本周是编程范式系列的最后一次分享,让我们拉长视角,看向远方,进入"元编程"的领域,在<冒号课堂>中起了个很酷的名字:"超级 ...

  2. 小课堂week17 编程范式巡礼第二季 并发那些事

    编程范式巡礼第二季 并发那些事 继续上周的编程范式话题,今天想聊一下并发范式. 并发也算一种范式? 真正的并发式编程,绝不只是调用线程API或使用synchronized.lock之类的关键字那么简单 ...

  3. 小课堂week18 编程范式巡礼第三季 谈谈依赖反转

    编程范式巡礼第三季--谈谈依赖反转 今天会进入深一点的主题,谈一个软件开发的"道":依赖反转.根据我的观察,这也是架构师与程序员的分水岭之一. 什么是依赖反转 引出问题 让我们从U ...

  4. 冒号课堂 编程范式与OOP思想

    上篇:编程范式与编程语言 第1课 开班导言 第2课 重要范式 第3课 常用范式 第4课 重温范式 第5课 语言小谈 第6课 语言简评 下篇:抽象机制与对象范式 第7课 抽象封装 第8课 抽象接口 第9 ...

  5. scratch少儿编程第一季——02、scratch界面介绍

    各位小伙伴大家好: 上期我们简单的介绍了Scratch的一些基本信息,和scratch软件的下载. 今天我们一起来了解一下Scratch的编程界面的介绍. 关于版本我考虑之后还是决定基于Scratch ...

  6. JAVA入门第一季(mooc-笔记)

    笔记相关信息 /** * @subject <学习与创业>作业1 * @author 信管1142班 201411671210 赖俊杰 * @className <JAVA入门第一季 ...

  7. Hadoop 2.x从零基础到挑战百万年薪第一季

    鉴于目前大数据Hadoop 2.x被企业广泛使用,在实际的企业项目中需要更加深入的灵活运用,并且Hadoop 2.x是大数据平台处理 的框架的基石,尤其在海量数据的存储HDFS.分布式资源管理和任务调 ...

  8. 编程范式:命令式编程(Imperative)、声明式编程(Declarative)和函数式编程(Functional)

    主要的编程范式有三种:命令式编程,声明式编程和函数式编程. 命令式编程: 命令式编程的主要思想是关注计算机执行的步骤,即一步一步告诉计算机先做什么再做什么. 比如:如果你想在一个数字集合 collec ...

  9. Lambda01 编程范式、lambda表达式与匿名内部类、函数式接口、lambda表达式的写法

    1 编程范式 主要的编程范式有三种:命令式编程,声明式编程和函数式编程. 1.1 命令式编程 关注计算机执行的步骤,就是告诉计算机先做什么后做什么 1.2 声明式编程 表达程序的执行逻辑,就是告诉计算 ...

随机推荐

  1. 小学生都能理解的原生js——call

    关于 js 作用域和执行上下文就不过多介绍了,本人也是在网上搜集了各种教程才逐渐理解,以下简单理解并说下call 的作用 首先简单理解下执行上下文有关概念,this 的指向就代表当前执行环境的上下文 ...

  2. elementUI 学习入门之 layout 布局

    layout 布局 通过基础的 24 分栏,可进行快速布局 基础布局 使用单一分栏创建基础的栅格布局, 通过 span 属性指定每栏的大小 <el-col :span="8" ...

  3. SQL必知必会 -------- order by、where等

    一.排序检索数据 1.排序数据:SELECT prod_name FROM Products ORDER BY prod_name(对prod_name列以字母顺序排序数据) ORDER BY子句的位 ...

  4. URAL 1995 Illegal spices

    构造. 前$n-k$个都是$1$,最后$k$个进行构造,首先选择填与上一个数字一样,如果不可行,那么这一格的值$+1$. #include<map> #include<set> ...

  5. luogu P4115 Qtree4

    题目链接 luogu P4115 Qtree4 题解 动态点分治,和上一题一样.同样三个堆.就是带权,用边权替换深度就好 为什么要单独写这个题解呢,因为我卡常卡了一天....据说树剖比rmq快? 在第 ...

  6. BZOJ 2612 [Poi2003]Sums(最短路)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2612 [题目大意] 给定a数组,问num能否被表示为a[1]*x[1]+a[2]*x[ ...

  7. centos 7 修改ssh登录端口

    在阿里云上面使用的oneinstack镜像,默认是使用的22端口,每次登录总会发现有人在暴力破解我的服务器,所以想想还是修改一下比较安全. 1.在防火墙打开新的端口 iptables -I INPUT ...

  8. BZOJ1002輪狀病毒 暴搜 + 找規律 + 高精度

    @[暴搜, 找規律, 高精度] Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个\(n\)轮状基由圆环上\(n\)个不同的基原子和圆心处一个核原子构成的,2个 ...

  9. bzoj 3594

    题解见: http://blog.csdn.net/qpswwww/article/details/44407371 收获: 1.对于一个问题,看似不可做,但一定存在一定特点,我们要做的就是找出一些特 ...

  10. 27.prim算法  最优布线问题(wire.cpp)

    [例4-10].最优布线问题(wire.cpp) [问题描述] 学校有n台计算机,为了方便数据传输,现要将它们用数据线连接起来.两台计算机被连接是指它们间有数据线连接.由于计算机所处的位置不同,因此不 ...