设计过程与1985年初版

1985年,David Turner设计的Miranda由Research Software Limited推出初版。这项设计在1983至1986年间逐步成形,初次发布发生在设计持续完善的过程中。Turner当时署名的工作机构是英国坎特伯雷的肯特大学计算实验室。Miranda继承了St Andrews Static Language(SASL)的部分设计,并采用此前在Kent Recursive Calculator(KRC)中试验的带守卫方程与列表推导式。KRC原是面向教学的小型语言;Miranda则把这些表达手段带进较完整的系统。Turner后来回顾设计时说明,在记号上,他用大写字母开头的名字表示数据构造子,小写字母开头的名字表示变量,使结构匹配与函数定义可以区分。守卫附在方程右侧,用条件区分不同答案;where的局部定义同时管辖右侧表达式及其守卫。

Turner在1985年的论文中说明,他希望把函数式编程研究成果变成稳定、有文档的语言实现,供更多人使用。为处理较大的程序,系统加入多态类型体系,以及保持类型一致性的程序库、分开编译和连接机制。

参考:[1] [2]

早期系统如何供人使用

1985年的技术说明把Miranda程序称作脚本:脚本由定义函数及其他对象的递归方程组成,没有命令式语句。各项定义通常不必按使用先后排列;局部定义通过where引入,内层缩进帮助编译器确定作用范围。代码表达对象之间的关系,而不是逐条安排机器动作。

这个早期实现嵌在UNIX交互系统中,配有屏幕编辑器、联机参考手册及操作系统接口。程序库可以分开编译,目标文件由系统自动更新。使用者不必手工维护这些文件。论文还感谢肯特大学的Simon Thompson指出早期抽象类型机制的缺陷。

参考:[2]

求和方程与按需求值

Turner的综述用列表求和展示模式匹配:空列表的和为零;非空列表则拆成首项与余下列表,把首项加到余项之和上。两种情况各写一条方程,选择依据就是输入的形状。这种写法把结束条件和递归步骤直接放在定义里,读者不需要另找循环计数器。

Miranda还采用惰性求值,只有结果确实需要某个子表达式时才计算它。例如条件函数可以在条件成立时返回零,在不成立时取倒数;当输入为零而选中第一支时,另一支的除法无需执行。无限列表也依靠同一机制存在,程序可逐步索取其中的元素,而不必先把整个序列算完。

参考:[3]

省略类型声明仍能检查程序

类型推断使简短的方程写法不必以放弃检查为代价。系统手册以给字符串添上复数词尾的函数说明:从连接字符串这一操作,编译器就能推断参数与结果都是字符列表。作者仍可显式填写类型,系统随后核对声明与定义是否相容。

多态则允许同一函数处理多种类型。恒等函数原样返回传入的对象,其参数和结果类型相同,却不限定为数字或字符。列表的各元素必须属于同一种类型;需要混放不同类型的成分时,可以使用元组。这些区别由静态分析检查,而不是等到每次执行时才猜测。

参考:[4]

后续版本须与首发分开

初版以后,Miranda又在1987年和1989年推出后续版本。1989年10月的第二版增加了供参数化脚本使用的%free指令和任意精度整数,并改进编译器与运行系统的速度。现存手册又经2006年5月小幅修订,故不能把其中列出的全部能力倒推给1985年初版。

参考:[1] [4]

传播与Haskell的分岔

Miranda随后进入大学与企业。Haskell设计者的历史论文记载,到1990年代初,它安装在20个国家的250所大学和约50家公司;论文特别提醒,安装不等于实际开课。这些数字描述后来的传播,不能当作初版推出当年的规模。

1987年,筹划共同函数式语言的研究者曾考虑以Miranda为起点。Turner希望维持单一标准和程序可移植性,没有同意这一安排;新语言团队则希望允许自由修改和分发实现。Haskell最终另行设计,但在方程定义、模式匹配、列表表示等方面吸收了Miranda的经验。两者的分岔也体现了稳定产品与开放研究工具的不同目标。研究者需要试验新的语言机制,Turner则重视Miranda用户之间的程序可移植性;这场协商把二者的要求明确区分开来。

参考:[5]