- 内容提要
- 序 1:程序里的世界
- 序 2:最后一层表象
- 关于本书
- 致谢
- 引言:简单的本源
- 篇一:计算系统
- 第 1 章 数,以及对数据的性质的思考
- 第 2 章 逻辑
- 第 3 章 抽象
- 篇二:语言及其面临的系统
- 第 4 章 语言
- 第 5 章 从功能到系统
- 篇三:程序设计的核心思想
- 第 6 章 数据结构:顺序存储
- 第 7 章 数据结构:散列存储
- 第 8 章 执行体与它在执行过程中的环境
- 第 9 章 语法树及其执行过程
- 第 10 章 对象系统:表达、使用与模式
- 篇四:应用开发基础
- 第 11 章 应用开发的背景与成因
- 第 12 章 应用开发技术
- 第 13 章 开发视角下的工程问题
- 第 14 章 应用程序设计语言的复杂性
- 篇五:系统的基础部件
- 第 15 章 分布
- 第 16 章 依赖
- 第 17 章 消息
- 第 18 章 系统
- 篇六:系统的基本组织方法与原理
- 第 19 章 行为的组织及其抽象
- 第 20 章 领域间的组织
- 附一:主要编程范式 及其语言特性关系
- 附二:继承与混合,略谈系统的构建方式
- 附三:像大师们一样思考——从 UML 何时死掉 谈起
- 附四:VCL 已死,RAD 已死
附一:主要编程范式 及其语言特性关系
节选自博客文章“‘主要的编程范式’及其语言特性关系”(2009 年 10 月)。文章对 Peter Van Roy 的“主要编程范式”一图进行了解读,Peter Van Roy 的原文参见: www.info.ucl.ac.be/~pvr/paradigms.html
【一】
Peter 将一个最重要的概念“state”引入进来。而这个 state 也是 Peter 对语言进行分类并考察其变化的主要依据。但 Peter 所使用的 state 概念以及专用名词“cells”都相当地令人困惑。所以在这个图的补充说明中,Peter 对此专门做了解释:“状态是记忆信息的一种能力,更精确地说,是及时存贮值序列的能力。”
你觉得这个概念像什么?对了,的确,非常像是“变量”。事实上,状态在编程核心概念的“数据逻辑”抽象中,表明的正是“数据的可变性”。也就是说,数据的可变性表现为状态。更进一步地,当数据被命名时,它称为变量或常量;当数据未被命名时,它成为游离的、无名称的、时序含义的存储单元,即“cells”。这也是 Peter 使用“cells”这个专用名词的原因:在本图的讨论中,需要从“变量/常量”这样的概念中,剥离掉“未命名或命名的、确定的或非确定的,以及串行的或并发的”这三个方面的性质。
当不考虑一个存储位置上的命名特性时,它就既非变量或常量,也非某个确定的运算对象(例如“对象”等高级的抽象概念),而只是一种更加泛义的“状态”;同时存储这个状态本身的事物,由于没有位置、时序等概念,所以被称为“cells”。
【二】
《程序设计语言:实践之路》这本书解释过命令式语言的本质特性,即用算法改变数据。如果用两个以上的逻辑(例如两行代码)去影响同一个存储位置(cells),使它的状态改变,并最终在该 cell 产生运算结果,那么它就是一种命令式语言。
再简单一点(但没有上面这样严谨)地说:在程序中不断地重写变量,变量值即是程序的最终结果。所以在本图中,Peter 把这个衍生关系表达为:命令式 = 纯数据 + 算法 + 状态维护。
无论是在串行还是在并发的编程中,命令式编程范式对“状态”的理解都是:共享状态。在串行(例如单线程)的编程中,状态是时序相关的。因为不断地重写“状态(数据/cells/变量)”,所以前一行和后一行所面对都是同一个共享状态的不同的值/副本。在这个过程中,正因为状态与时序相关,所以前一分钟与后一分钟的状态是不确定的。但是在同一时刻,这个状态是确定的。
与上面相类似地,在多线程中,同一时刻,不同线程也将面临这个值/副本。但正是因为多线程(并发)中,线程 A 与线程 B 对于同一个 cell,在同一时刻所得到的状态也是不确定的——我们可以假想为多核 CPU 在对同一个内存地址读写(于是就出现了我们所谓的“同步”问题,进而也就出现了“锁”的问题)。所以在这个分支中,当加入“线程”概念之后,新的编程范式全都变成了“可观测的非确定性”为“yes”的情况。
【三】
我们显然可以发现,问题出在由于多个线程都在“写 cell”。在命令式的解决方案中,采用的方法是“加锁”;持锁存取的最经济的方法之一是“多读单写”,即保证同时只有一个线程能“写 cell”。
但是这给应用带来了负担。如果一个应用程序有多个线程(分布或不分布在多个 CPU 核上),在它们都要读取同一个 cell 而又有某个线程要写该 cell 时,那么大家就都要被挂起来,直到这个写操作完成。整个应用程序在 CPU 使用(或者说效率)上就大大打了折扣。
如果这只是一个桌面程序(例如记事本),大概没人会说什么。但如果这是个服务器程序(例如 WWW Service),那么整个网络、所有的会话就都处于等待状态了,但同时,服务器的 CPU 占用可能会远远小于 1%!
解决问题的终极方法,就是不解决这个问题。既然写 cell 带来了问题,那么我们就“不写 cell”。我们由前面所有讲述的内容开始倒推,问题根本是由“命令式语言”这个编程范式本身决定的:用算法改变数据。
所以我们回到了原始的问题:如果算法不改变 cells(数据/状态/变量)呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论