- 内容提要
- 序 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 已死
17.3 消息是剥离了所有数据性质的状态
状态与消息其实是一个统而一之的东西,它们不过是两个程序设计范式对同一事物的不同叙述。这样我们又回到了最初讨论问题的方式,即“两个侧像”。
回顾此前的讨论,我们曾经设定数据的全部性质中有一个不可或缺的子集为 标识 、 值和确定性 。其中值是数据的本义,标识是人与计算机进行沟通时所需的抽象定义 6 ,确定性则是数据与使用这些数据的计算系统的最终极的问题 7 。基本上,我们可以将数据在计算机语言中抽象描述为图 47 8 :
图 47 数据在计算机语言中的种种抽象与概念递进关系
但是我们上面讨论的 状态 ,是否需要全部三个性质呢?
这一设问的关键在于:我们将状态Sx作为数据全集x的一个分量,就意味着Sx的三种性质与x的其他分量x’、*x“必须是协同分布的 9 。因此设问若成立,就意味着任意一个数据在其分布过程中都要保证这三种特性的协同分布。例如数据 A,其分布为 A1, … , An,在同一时刻 A1, … , An*都必须是同时确定的,或同时不确定的。又例如——以其字面上的含义来看——我们必然面临类似的需求:在一个分布系统中的多个子系统中,要求同一个状态使用完全相同的标识。
对于状态,Peter Van Roy 是将它作为多种范式中对数据的不同理解来看待的 10 :
状态是记忆信息的一种能力,更精确地说,是及时存贮值序列的能力。它的表现能力极大地受到其所在范式的影响。我们将其表现能力划分出四个等级,它们的不同在于状态是未命名的或命名的、确定的或非确定的,以及串行的或并发的……非确定性对真实世界中的交互很重要(例如在“客户端/服务器”编程模型中),而命名状态则对模块化有着相当重要的意义。
在这一观念中,状态是一个可变的数据:表达 某个 存储位置上、 某时 的信息。换言之,数据的不确定性——包括其静态的确定性——表现为状态。这使得 状态 在概念上很类似于 变量 ,不过这也并没有什么不妥,毕竟在大多数语言中,我们的确是用变量来实现状态以及相关的机制。基于此,Peter Van Roy 非常深入地剖析了状态的数据性质。
把 Peter Van Roy 的思考逆向探讨一番,我们可以得出这样一个结论:当不考虑一个存储位置上的命名特性时,它就既非变量或常量,也非某个确定的运算对象(例如“对象”等高级的抽象概念),而只是一种更加泛义的“状态”;同时存储这个状态本身的事物,由于没有位置、时序等概念,所以借用我们之前使用过的名词,可以称之为“ 存储位置 (cells)”。
一旦我们不考虑这个存储位置本身的物理限制,而只考虑其中数据本身的、值的含义时,我们也就可以脱离系统(例如某个系统的多个子系统)地称之为“消息”。消息既是系统之间的 约定 ,也可以视为是游离于系统之间的、借着这些约定来约束系统的 数据 。
综上所述,状态与消息的抽象概念的区别在于:前者往往带有位置之于存储,或数据之于逻辑的含义;后者则将位置与逻辑含义都抽取掉,只认为消息是一个约定所需的数据部分。图 48 表达了二者的关系 11 。
图 48 约定规格:值性质下(状态与消息)与变量性质下(结构与对象)的抽象概念对比
其中,对于消息:
- 其数据规格部分是应用中的所需,而非概念上的必需;
- 约定所需的逻辑部分是由其他系统根据约定实现的;
- 约定(在概念上)是可遵守、可更新,以及可违约的。
既然其约定是一个非数据的规约,是系统间在逻辑实现上的约束,并且事实上这一约束也可能不被遵守,所以可以说:
消息就是消息,消息没有任何特定含义的性质。
return
既已用于表明 foo 的数据含义,则必然无法用于表示“含义与可操作性确定的、foo() 的整体含义”。即它不能既表示 foo() 的部分含义,同时又表示 foo() 的整体含义。这种“既是又非”有违于基本逻辑的矛盾律。 ↩- 我们用到了“通告”这个词,意味着消息的发布可以是单个的,也可以是多个的。前一种情况可以实现令牌式的同步,后一种则可以实现多读单写式的同步。 ↩
- 这些逻辑基于 M 的数据含义,即{*m’, m“*},它被 Step2 作为私有的数据信息加以处理。 ↩
- 同样地,当 Step2 发出消息 N 时,N 与 M,或 N 与{*m’, m“*}并没有必然关系。 ↩
- 这意味着,“发出消息”对于 Step1 来说是一个“有确定结果的确定行为”。这一确定结果是“没结果”,因为在 Step1 中不存在对这一结果任何有意义的依赖。而“函数调用”正好是存有对某种结果的依赖的。 ↩
- 这是程序设计语言的需求,即标识符(token)、名称(name)或词(word/keyword)的本义。 ↩
- 在之前的种种讨论(事实上也包括接下来的讨论)中,凡涉及对“数据性质中的确定性”的追问,必然会对我们在计算模型、语言范式等方面提出新的挑战。 ↩
- 在从变量到常量的概念变迁中,某些语言并不引入“常量”这一概念,而是通过强调“变量不可写”来强制数据必须具有确定性。在类似的语言范式(例如数据流范式)的基础观念中,通常还涉及变量仅作为标识符而未有确定值时的抽象。例如在 Oz 与 MapReduce 中,如果一个变量尚未绑定值,则它将阻止运算它的函数与任务(job 或 process),因为这时的运算也是不确定的。直到该变量存在一个确定值,阻止才得以解除。 ↩
- 这里的协同分布是指:未必一致,但至少是通过某种规则来约束。 ↩
- 引自 Peter Van Roy 对“主要编程范式”一图的说明。参见: www.info.ucl.ac.be/~pvr/paradigms.html ↩
- 该图也从侧面表达了变量与状态在数据性质上的相似性,以及在结构化程序设计和面向对象程序设计中“可以以结构、对象等类型化数据来实现 状态 ”这一事实。 ↩
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论