程序原本(二十六):语言及其面临的系统——从功能到系统(方向 1:计算要素的结构化)

阅读数:22 2019 年 9 月 28 日 18:10

程序原本(二十六):语言及其面临的系统——从功能到系统(方向1:计算要素的结构化)

第一种结构化方向是指:通过在计算要素上的结构化来增强计算能力。在这一方向上的努力,将我们的开发规模推进到程序(program)这一等级。我所见过的,对于程序的最初、最正确和最直观的定义为:

a+s(d)

即,“算法 + 数据结构 = 程序”1

1 这个著名的论断出自尼古拉斯•沃斯(Niklaus Wirth)。沃斯是 Pascal 语言之父,1984 年图灵奖获得者。《Algorithms + Data Structures = Programs》是他最有名的一本著作。

复制代码
Algorithm + Structured(Data)

但是这里的结构(structure)主要作用于数据(data),所描述的是对算法 (algorithms) 中所用数据的抽象。而在更大的计算规模中,计算对象——数据的复杂性固然是一个问题,而计算本身的复杂性也是一个问题。因此对于 a+s(d) 这个定义来说,Dijkstra 在《结构程序设计》中的描述更为完善,即:

s(f)+s(d)

显而易见,后者用计算的结构化 s(f) 来替代了算法 a。原意为2:对于一个计算过程,(通过提炼)抽去每次计算所处理的特殊值,余下的不变的东西就是这个“算法”自身。由于对过程中的每一步都进行了“动态提炼(算法)和静态提炼(数据结构)”,因此这里的提炼结果(结构 s)在计算过程 f 和数据 d 上是匹配的、共生的,即3

2 原文是“考虑一个算法和它所能引起的各种计算:从这些计算开始,抽去……”。如下一个脚注所谈到的,这里的计算过程是指 procedure,现在则常称为 function,也因此这里使用 s(f) 这个描述形式。

3 这里确实也可以表达为 s(f,d),但考虑到这里的 f 是必然作用于 d 的,因此无疑是说该 s() 必然实现为return s(f(d))

s(f(d))

其三,程序代码本身在组织上也还存在复杂性的问题。对于这第三个问题,Dijkstra 以“组织和编排程序”为主题加以了讨论。不过在具体背景之下,他所讨论的仅仅是对“函数 / 过程”4进行结构化地组织与编排。

4 在 Dijkstra 的叙述中,函数是偏向数学计算、有计算结果的;过程只是一段计算机处理,并不表明有计算数据返回。现在我们通常用函数来概含了二者,以 C 语言为例,过程是指返回值声明为 void 的函数。循此惯例,此后的讨论中将仅仅使用函数这一个名词。

这里需要明确一下在该背景下的函数这一概念。在上一小节的计算语言中,函数是与数学公理类同的、面向“数”或“数据”的一个计算过程。而在本小节所讨论的程序(program)这个规模之下(以及该规模下的语言之中),函数是算法或算法中的一个子步骤的代名词。在 program 这一语境下的函数,与确定的结构有关,既包括计算逻辑的结构,也包括计算数据的结构,是

s(f(d))

中三者合一的概念。如同《结构程序设计》用 **“珍珠”和“项链”来做的比喻一样,从珍珠的角度来看,是可以在整个程序中被替代、被优选的5;从项链的角度来看,可以是暂时不完整的6;从串起项链 ** 这件事上来看,顺序是确定的7

5 “程序比较(程序验证、测试)”以及渐进优化的思想基础。

6 “自顶向下”的结构化设计的思想基础。

7 “架构”以及框架、流程等产出的思想基础。

我将这一等级上的语言统称为 **“编程语言”(programming languages)。我使用这个具有歧义的称谓的原因在于8:这一类语言仍然是在计算要素 ** 上加以增强——尽管对于函数来说也存在着代码的组织与编排上的增强,但归根结底是针对计算要素的,并且是在该抽象上的自然延伸。

8 另外的原因在于,对于许多开发人员来说,在这个级别上的开发才是他们心目中的、(被院校教育所圈定的)计算机科学领域中的“编程”。以其后的例子来说,“写出一个操作系统”可能是许多开发人员心中的巨作。

在这一阶段中,计算机主要在专业领域中使用,计算量的增加是程序规模变化的主要原因,同时又要求对目标系统有足够的抽象表达能力,因此在数据抽象程度变高的同时仍然强调语言具有完备的计算能力。我们可以将操作系统、网络系统、通信调度、分布式运算环境等绝大多数基础系统的核心部分,以及其中大量利用系统特性的工具软件,都归于这类语言所面向的开发规模。其主要特点是:大量的计算、数据抽象与计算环境相关,主要算法可以在不同的软硬件环境中通用或重现,并且通常用户主要入口是操作系统的约定或直接的硬件系统界面。

评论

发布