微软推出新编程语言 Bosque,超越结构化程序设计
微软近期推出了一款全新的编程语言 Bosque,该语言参考了 TypeScript 的语法与类型,还有 ML 和 Node/JavaScript 的语义。作者微软计算机科学家 Mark Marron 致力于消除编程过程中出现的各种复杂情况,创造出了他认为超越主流结构化程序设计的 Bosque 这一语言。
结构化程序设计现在随处可见,不管你用的是 C/C++,还是 Java、Python 与 Golang 等编程语言,在开发过程中使用的基本都是这一程序设计思想,它最初是为了替换掉程序中弊大于利的 goto 语法而产生的。研究者使用结构化程序设计思想中的循环、顺序与选择等设计,最终完全替换掉了 goto 指令,并且这样的编程思想也一直流行至今。
Bosque 是随着 Mark 发表的论文《Regularized Programming with the BOSQUE Language》提出的,论文中,作者指出上世纪 70 年代兴起的结构化程序设计和抽象数据类型使得开发者可以屏蔽掉底层硬件架构的特征,专注于编写功能代码,同时开发也变得更加不易出错。而作者在此基础上,提出了一种新的程序设计思想——Regularized Programming(规范化/正则程序设计),通过避免低级循环动作的迭代处理、用代数数据转换操作符丰富语言等设计,超越结构化程序设计。
作者同时为此思想设计了全新的编程语言 Bosque。具体来讲,现有的程序设计得到简化,成为规范化形式,消除了主要的不确定复杂性来源。论文基于一系列分析、运行时与编程器开发的经验与验证,以及针对开发人员的采访,确定了开发过程中会出现的 5 个主要不确定复杂性来源:
- 可变状态和逻辑帧:将可变性引入编程语言破坏了以单调方式推理程序的能力,这迫使程序员(和任何分析工具)需要去确定在操作之后哪些东西还是有效的,而哪些又已经失效。同时可变代码返回值和对参数(或其它全局状态)产生副作用影响程序状态,也使得需要推理每个操作的逻辑帧。
- 循环、递归和不变量:循环和递归是推理的最基本挑战,因为代码描述了单个步骤的效果,但理解完整构造需要对一组值的量化属性进行泛化,不变量提供了所需的连接,但是一般来说这样的计算通用技术是无法实现的。
- 不确定的行为:不确定的行为包括未定义的、在指定的或非确定的环境行为,这需要程序员或分析工具来推理和解释所有可能的结果。例如:排序稳定性、地图/字典枚举顺序等。这些不确定的行为增加了开发过程的复杂性,并且随着时间的推移,慢慢地被视为应该被删除的技术债。
- 不遵循“数据不变”:编程语言通常为数组/元组中的单个元素或对象/记录中的字段提供访问与更新操作符,这些访问器/更新器在单个元素的基础上执行,导致程序员在多个步骤上更新对象的状态,此时通常持有的不变量在恢复之前暂时是失效的。在这些情况下,必须跟踪和恢复的细节数量会大大增加错误发生的可能性。
- 相等与别名:编程语言处于数学和工程的边界,虽然语言语义被表述为数学概念,但是存在一些常见情况,例如:引用相等、按值、按引用或评估顺序传递,这背后其实是默认了底层是冯·诺依曼架构。虽然看似微不足道,但这些选择对可理解性产生了重大影响,比如引用相等会导致关于别名关系推理的复杂性,并使其它架构的编译变得非常复杂。
这些不确定复杂性是程序各种 bug 的来源,增加了开发者理解和实现应用功能的复杂性,同时使程序自动推理也变得非常复杂,或完全不可行。
其中,根据科技媒体 The Register 对 Mark 的采访,Mark 认为可变状态、循环和引用相等这三者的问题是最突出的。
以引用相等为例,Mark 指出,当两个变量指向内存中的同一个对象时,问题的复杂性就提高了,“看起来非常简单,但是一旦你在语义中出现引用相等,那么就必须不断地考虑它和它引入的指针别名的关系。”
而最为熟悉的循环机制也带来不小的复杂性,在 Bosque 中它被取消了,下边是一个等同于 JavaScript 中 for 循环的例子:
- //Functor (Bosque)
- var a = List[Int]@{...};
- //Pre: true
- var b = a.map[Int](fn(x) => x*2);
- //Post: List[Int]::eq(fn(x, y) => y == x*2, a, b)