MUMPS: a linguagem que nasceu no hospital

Depois de publicar um artigo sobre o Natural, um amigo no Linkedin sugeriu que eu falasse sobre outra linguagem de programação. Segundo ele, uma grande promessa nos anos 1980.

Confesso que MUMPS não foi uma linguagem com a qual tive contato profissional. Mas, pesquisando sua história, descobri que ela nasceu para resolver problemas muito específicos de um hospital, conquistou espaço em outros setores e continua presente em sistemas importantes quase sessenta anos depois.

E, diferentemente de muitas linguagens que surgiram naquela época, MUMPS não foi criada por uma fabricante de computadores ou por uma empresa de software.

Quando um hospital precisava de seu próprio computador

Na década de 1960, a informatização hospitalar ainda estava dando seus primeiros passos. Hospitais precisavam administrar informações sobre pacientes, internações, exames, medicamentos e procedimentos. Mas os computadores disponíveis eram caros, possuíam pouca memória e não haviam sido projetados especificamente para esse tipo de aplicação.

No Massachusetts General Hospital, em Boston, dois programadores procuravam construir um sistema que permitisse a diferentes profissionais consultar e atualizar informações hospitalares simultaneamente. O problema era que as ferramentas disponíveis não atendiam satisfatoriamente às necessidades do projeto.

Foi nesse contexto que Neil Pappalardo e Curt Marble desenvolveram o MUMPS, sigla para “Massachusetts General Hospital Utility Multi-Programming System”.

O trabalho começou em 1966, e a primeira implementação entrou em funcionamento em 1967, utilizando um minicomputador DEC PDP-7 com apenas 8 KB de memória e três terminais de teletipo. Posteriormente, o sistema foi transferido para um PDP-9, que permitiu ampliar o número de usuários simultâneos. Esses minicomputadores eram fabricados pela Digital Equipment Corporation, a DEC.

O objetivo não era simplesmente criar mais uma linguagem de programação. Era construir um ambiente completo para desenvolver e executar aplicações hospitalares, integrando processamento, armazenamento, acesso aos dados e compartilhamento de informações entre usuários.

Uma linguagem que também entendia de banco de dados

Uma das características mais interessantes do MUMPS era sua integração com o armazenamento de dados.

Em COBOL, tradicionalmente, o programador precisa definir estruturas de registros e utilizar comandos específicos para recuperar ou atualizar informações, seja em arquivos convencionais, seja por meio de um sistema gerenciador de banco de dados.

O MUMPS adotou uma abordagem diferente.

A linguagem oferecia variáveis locais, utilizadas durante a execução dos programas, e variáveis globais, cujos valores eram persistidos e compartilhados entre diferentes processos. Essas variáveis globais eram organizadas em estruturas hierárquicas, permitindo representar informações com diferentes níveis de detalhamento. A localização física desses valores era determinada pelo próprio sistema, e não pelos programas.

Imagine, por exemplo, um cadastro de pacientes com informações como nome, data de nascimento, telefone e e-mail. Em uma aplicação COBOL tradicional que utiliza um arquivo VSAM ou uma tabela de dados, cada registro possui espaço reservado para todos esses campos, mesmo quando alguns não estão preenchidos. No MUMPS, os dados são armazenados em uma estrutura hierárquica de variáveis globais. Se determinado paciente não possui telefone ou e-mail cadastrado, os elementos correspondentes simplesmente não precisam existir na estrutura de armazenamento. Era uma solução particularmente interessante para registros médicos, nos quais pacientes diferentes podem possuir conjuntos muito distintos de informações.

Décadas antes da popularização dos bancos de dados NoSQL, o MUMPS já oferecia algumas características que hoje associamos a essas tecnologias: armazenamento de informações sem um esquema rígido, organização hierárquica dos dados e acesso direto por chaves. Não se tratava de um banco NoSQL no sentido moderno, mas de uma arquitetura que antecipou algumas das ideias que voltariam a ganhar destaque muitos anos depois.

Menos código para acessar informações?

Para entender essa integração, imagine uma aplicação que precisa listar o nome de todos os pacientes armazenados em um arquivo VSAM:

PERFORM UNTIL WS-FIM = 'S'
   READ ARQ-PACIENTES NEXT RECORD
      AT END
         MOVE 'S' TO WS-FIM
      NOT AT END
         DISPLAY PAC-ID ' - ' PAC-NOME
   END-READ
END-PERFORM

Em MUMPS, a mesma ideia poderia ser expressa assim:

SET ID=0
FOR SET ID=$ORDER(^PACIENTE(ID)) QUIT:ID=""
. WRITE !,ID," - ",^PACIENTE(ID,"NOME")

O caractere ^ identifica uma variável global administrada pelo MUMPS. No exemplo, ^PACIENTE representa uma estrutura hierárquica na qual cada identificador de paciente corresponde a um subscrito, e NOME identifica uma informação associada a esse paciente.

No MUMPS, o armazenamento persistente fazia parte da própria linguagem. Essa integração eliminava uma quantidade considerável de código que, em outras arquiteturas, seria necessária para realizar operações de entrada e saída. Mas também produzia uma consequência importante: os programas passavam a depender profundamente da maneira como aquele ambiente organizava e manipulava seus dados.

E o MUMPS chegou aos mainframes IBM?

Sim. Mas sua história nos mainframes foi bastante diferente da trajetória do COBOL, do PL/I ou do Natural.

Durante os anos 1970 e 1980, surgiram diferentes implementações de MUMPS para computadores da DEC, sistemas Unix, microcomputadores e também máquinas IBM. Entre elas estavam versões destinadas ao ambiente VM/CMS dos mainframes IBM System/370.

O VM/370, antecessor do atual z/VM, era um sistema operacional que permitia criar máquinas virtuais, cada uma com seu próprio ambiente de execução, compartilhando os recursos físicos do mainframe. Nessas máquinas virtuais, era possível executar o CMS, ambiente interativo no qual funcionavam implementações do MUMPS.

Existiram implementações comerciais como o M/VM, da InterSystems, e o MSM/VM, da Micronetics. A própria IBM chegou a comercializar o MUMPS/VM, que aparece em seu catálogo de software de 1991.

O MUMPS não ocupou o mesmo espaço do COBOL, do PL/I ou do Natural. Seu desenvolvimento e sua adoção estavam muito mais associados ao ecossistema de sistemas de informação hospitalares e a implementações especializadas da linguagem, frequentemente executadas em plataformas de outros fabricantes.

Uma tecnologia que cresceu longe dos holofotes

O MUMPS também passou por processos de padronização, permitindo que diferentes implementações compartilhassem uma definição comum da linguagem. Mas havia características que podiam tornar seu código pouco familiar para programadores acostumados com COBOL.

A linguagem permitia abreviar comandos, utilizava estruturas de dados bastante flexíveis e possuía construções sintáticas compactas, concebidas em uma época na qual memória e armazenamento eram recursos extremamente limitados.

Por exemplo, comandos como SET, FOR, QUIT e WRITE podiam ser escritos simplesmente como S, F, Q e W. Até funções internas, como $ORDER, podiam ser abreviadas para $O. Essa concisão fazia sentido em uma época de terminais lentos e recursos computacionais limitados, mas também permitia escrever programas difíceis de compreender, especialmente para quem não estivesse familiarizado com a linguagem.

O trecho que mostrei acima…

SET ID=0
FOR SET ID=$ORDER(^PACIENTE(ID)) QUIT:ID=""
. WRITE !,ID," - ",^PACIENTE(ID,"NOME")

…podia ser abreviado da seguinte forma:

S ID=0
F S ID=$O(^PACIENTE(ID)) Q:ID=""
. W !,ID," - ",^PACIENTE(ID,"NOME")

Programas que abusavam de abreviações, referências indiretas e convenções pouco explícitas podiam se tornar difíceis de compreender e manter.

O problema, portanto, não era muito diferente daquele que encontramos em outras linguagens: recursos criados para facilitar o desenvolvimento também podiam produzir sistemas complexos quando utilizados sem disciplina de engenharia.

E, como aconteceu com Natural, a integração entre linguagem, banco de dados e ambiente de execução podia tornar uma futura migração bastante trabalhosa.

Substituir MUMPS não significava apenas traduzir comandos para COBOL, Java ou qualquer outra linguagem. Era necessário compreender como os programas organizavam suas informações e como diferentes aplicações compartilhavam aquelas estruturas persistentes.

Que fim levou o MUMPS?

Sua descendência continua presente em alguns dos sistemas de informação mais importantes do mundo. Um dos exemplos mais conhecidos é o VistA, sistema de informações hospitalares desenvolvido pelo Departamento de Assuntos de Veteranos dos Estados Unidos, o VA.

O VistA utiliza tecnologia MUMPS para sustentar aplicações clínicas e administrativas, incluindo informações de pacientes, prescrições, exames e outros processos hospitalares.

Em 2017, o governo norte-americano iniciou um programa para substituir o VistA por uma solução comercial de prontuário eletrônico, atualmente fornecida pela Oracle Health. Entretanto, a modernização enfrentou problemas de confiabilidade, riscos à segurança dos pacientes e resistência dos profissionais de saúde, levando à suspensão das novas implantações em 2023. O programa foi retomado, com a meta de concluir a substituição até 2031 e um custo total projetado de US$ 37,2 bilhões. Enquanto isso, o VistA continua sustentando as operações das unidades que ainda não migraram. Esse filme a gente já assistiu várias vezes.

Outro exemplo é a Epic, uma das principais empresas fornecedoras de sistemas de prontuário eletrônico dos Estados Unidos. A Epic possui uma longa história de utilização de tecnologias da InterSystems, empresa cuja trajetória está diretamente relacionada às implementações comerciais de MUMPS. Em 2020, a Epic anunciou a adoção da plataforma InterSystems IRIS, sucessora tecnológica de produtos como o Caché.

E a história não termina na saúde. O GT.M, uma implementação da linguagem desenvolvida originalmente nos anos 1980, também encontrou aplicações no setor bancário. Seu código deu origem ao YottaDB, um banco de dados de código aberto que preserva compatibilidade com a linguagem M e amplia suas possibilidades de integração com outras tecnologias.

Nem todas essas aplicações foram escritas em MUMPS, mas todas possuem alguma relação com a tecnologia que começou a ser desenvolvida naquele PDP-7.

Por que algumas linguagens sobrevivem?

Costumamos avaliar linguagens de programação pela quantidade de profissionais que as utilizam, pela presença em cursos universitários, pela popularidade nas comunidades de desenvolvimento ou pela frequência com que aparecem nas discussões sobre novas arquiteturas. Mas esses indicadores não dizem necessariamente quanto uma tecnologia continua sendo importante para as organizações.

MUMPS nasceu para resolver um problema concreto. Seus criadores precisavam armazenar informações complexas, permitir acesso simultâneo e trabalhar com computadores que possuíam recursos extremamente limitados. A solução desenvolvida naquele hospital acabou reunindo características que continuaram valiosas mesmo depois de várias gerações de computadores e linguagens de programação.

Uma tecnologia não precisa continuar popular para que as ideias que a tornaram importante continuem relevantes.