MUMPS 76 入门指南周年纪念版发布
速览
本文介绍了 MUMPS 76 入门指南的周年纪念版本。该指南旨在帮助开发者理解和使用 MUMPS 语言。作为经典数据库语言的参考资料,其更新具有纪念意义。
AI 深度解读
The MUMPS 76 Primer – Anniversary Edition 深度解读
背景
1966年,在波士顿麻省总医院(Massachusetts General Hospital)的计算机实验室,Octo Barnett、Neil Pappalardo 和 Curtis Marble 共同创造了一种名为 MUMPS(Massachusetts General Hospital Utility Multi-Programming System,麻省总医院实用多编程系统)的编程语言。
MUMPS 的诞生源于一个极其务实的需求:医院需要一种系统,允许医生和护士在廉价的硬件上,通过多个终端同时访问和更新患者数据,且必须是实时的。在1966年,“廉价硬件”指的是拥有8K字内存和小型磁盘的 DEC PDP-7。在这种资源极度受限的环境下,没有空间去堆叠独立的操作系统、文件系统、数据库服务器和应用程序语言。一切必须整合为一个统一的系统。
最终诞生的成果令人瞩目:一种内置了层次化数据库的编程语言——这在四十多年后才被数据库界正式命名为“NoSQL 数据库”。MUMPS 的核心数据抽象是“全局变量”(Global Variable),这是一种层次化的稀疏数组,持久存储在磁盘上,并被所有并发用户共享。用今天的术语来说,全局变量是一种无模式(Schema-free)、有序的键值存储,支持复合键,在首次赋值时创建,按需删除。
例如:
SET ^PATIENT(12345,"NAME")="Smith, John"
SET ^PATIENT(12345,"DOB")="1945-03-15"
SET ^PATIENT(12345,"LAB","2024-01-15","GLUCOSE")=95
这里没有 CREATE TABLE,没有模式定义,也没有 INSERT 语句。你只需在一个层次化路径上 SET 一个值,系统会自动创建所需的中间节点。KILL 一个节点,其下的整个子树都会消失。
MUMPS 在1966年就具备了后来其他计算领域花费数十年重新发明的特性:
- 无模式存储:无需声明,节点在首次赋值时创建。这是 MongoDB 在2009年所谓的“无模式文档”。
- 层次化数据模型:患者记录天然形成树状结构。MUMPS 全局变量直接镜像了这一结构。这是 Firebase 在2012年所谓的“实时层次化数据”。
- 有序键遍历:
$NEXT函数在不显式索引的情况下,按排序顺序遍历兄弟节点。这是 Redis 在2009年所谓的“有序集合”,或 LevelDB 在2011年所谓的“有序迭代”。 - 集成化的语言与数据库:不存在阻抗失配。变量和数据库节点使用相同的语法、相同的数据类型和相同的操作。
所有这些功能都在一台仅有8KB内存的机器上运行,并服务于多个并发用户。
到了20世纪70年代初,多家供应商创建了彼此不兼容的 MUMPS 方言。1972年成立的 MUMPS 开发委员会(MDC)致力于创建共同标准。结果于1976年1月由美国国家标准局(NBS)作为 NBS Handbook 118 发布:“MUMPS 语言标准”。同年晚些时候,Melvin Conway(以“Conway 定律”闻名)撰写了配套文档《程序员参考手册》(MDC/42)。这两份文档共同构成了 MUMPS 第一个完整、正式的规范。
本指南专门针对这一1976年标准——即经过数十年扩展之前的、精炼核心的 MUMPS。本书面向至少精通一门其他语言的程序员,旨在帮助他们理解 MUMPS 是什么、如何工作以及其历史意义。
核心内容
本部分基于1976年 MUMPS 标准,详细解读其语言特性、命令、函数及数据结构。
1. 语言概览与数据类型
MUMPS 只有一种数据类型:字符字符串。数字仅仅是看起来像数字的字符串。字符串 "42" 和数字 42 是相同的值。执行算术运算时,MUMPS 自动将字符串解释为数字;进行连接时,则将值视为字符串。没有类型声明,没有类型错误,也无需担心类型转换。
2. 运算符与表达式
所有二元运算符严格按从左到右的顺序求值。不存在“先乘除后加减”的规则。
- 表达式
2+3*4的结果是20,而不是14。因为先计算2+3得到5,然后5*4得到20。 - 使用括号可以覆盖此规则:
2+(3*4)得到14。 这种设计虽然陌生,但消除了因误解优先级而导致的一类错误。
3. 程序结构与语法
MUMPS 程序由一系列行组成。每行包含:
- 可选的标签(供
DO、GOTO或$TEXT引用)。 - 强制性的空格分隔符。
- 零个或多个由单个空格分隔的命令。
- 以分号
;开头的注释,延伸至行尾。
空格具有语法意义:
- 单个空格分隔命令字与其参数。
- 两个空格(或行尾)分隔无参数命令与下一个命令或注释。
每个命令都有全称和一个字母的缩写,两者始终有效。例如 SET X=1 和 S X=1 是相同的。
4. 核心命令 (Commands)
1976年标准定义了19个命令:
- SET (S):赋值。
- WRITE (W):输出数据。逗号后的
!是格式代码,产生换行。例如WRITE "Hello, World!",!。 - READ (R):输入数据。
- IF / ELSE:条件执行。
- Post-Conditionals:后置条件(如
IF condition DO ...)。 - FOR:循环。
- DO:调用子程序。
- GOTO:转移控制。
- QUIT (Q):从子程序返回或退出
FOR循环。 - HALT / HANG:停止或挂起程序。
- XECUTE (XEC):将字符串作为代码执行。
- KILL (KILL):删除变量。
- BREAK:中断。
- 其他包括:
CLOSE,LOCK,OPEN,USE,VIEW。
注意:1976年标准中没有 JOB 命令(无编程多任务),也没有 NEW 命令(无局部变量作用域,该功能于1984年引入)。
5. 字符串函数 (String Functions)
1976年标准定义了12个函数:
- $LENGTH:字符串长度。
- $EXTRACT:按位置提取子串。
- $PIECE:按分隔符提取子串。
- $FIND:搜索子串。
- $JUSTIFY:右对齐并格式化数字。
- $ASCII / $CHAR:字符代码转换。
- $RANDOM:随机数。
- $SELECT:条件表达式。
- $TEXT:检索源代码行。
- 其他包括:
$DATA,$NEXT。
6. 全局数据库 (The Global Database)
MUMPS 的核心是其内置的层次化数据库。
- 全局变量:以
^开头,后接名称和可选的下标。 - 层次结构:支持多维下标,形成树状结构。
- 持久化:数据自动存储在磁盘上。
- 并发共享:所有用户共享同一数据空间。
7. 特殊变量 (Special Variables)
1976年标准定义了7个特殊变量:
$HOROLOG:日期
