Torben Mogensen header

Har Sundhedsplatformen fåresyge?

Der har i de seneste dage været en del diskussion om Sundhedsplatformen.

Dels har Kristian Tørnings gæsteblog kritiseret, at systemet er proprietært, hvilket binder regionen til leverandøren, og at systemet er kodet i et relativt ukendt sprog kaldet MUMPS, hvilket gør det svært at finde udviklere.

Andre steder (bl.a. i Radio 24/7 her til morgen) har Sundhedsplatformen været kritiseret for at være bygget på en forældet kerne. Sundhedsplatformen er bygget på systemet EPIC fra et Winsconsinbaseret firma af samme navn, og bygger på databasesystemet Caché fra InterSystems. Caché databasen er oprindeligt udviklet i 1997, men er løbende blevet opdateret.

Jeg kender ikke arkitekturen i EPIC og Caché, og arkitektur er heller ikke mit resortområde, så jeg vil ikke kommentere yderligere på denne, udover at nævne at min kollega Jørgen Bansler har udtrykt bekymringer om platformen, men mestendels fordi den er bygget til det amerikanske sundhedssystem og kun besværligt lader sig tilpasse det danske.

MUMPS er ikke meget ældre end C

Jeg vil dog snakke lidt om programmeringssproget, da sprog er mit område.

Caché og EPIC er begge skrevet i programmeringssproget MUMPS. MUMPS blev oprindeligt udviklet i 1966-1967 på Massachusetts General Hospital, og navnet er en forkortelse for "Massachusetts General Hospital Utility Multi-Programming System", men forkortelsen er sikkert også valgt fordi "mumps" på engelsk betyder "fåresyge".

MUMPS er sidenhen blevet videreudviklet, og den seneste ANSI standard er fra 1995 (og godkendt af ISO i 1999 og igen i 2010).

Der findes Open-Source implementeringer af MUMPS, der kan køre på f.eks. Raspberry Pi. Sproget er altså ikke væsentligt ældre end f.eks. C, som bliver flittigt brugt, så alderen alene burde ikke være en hindring for at bruge det.

Men er der andre ting, der taler for eller imod brug af MUMPS til Sundhedsplatformen?

MUMPS er designet omkring en hierarkisk database, og variable med "^" som præfiks er persistente i databasen, og vil være tilgængelige for alle programmer, der deler denne database. Semantikken er transaktionssikker (ACID), så systemer skrevet i MUMPS er generelt robuste.

Datatyper i MUMPS er strings og multidimensionale arrays, som bruger vilkårlige værdier som indices. Det minder på den måde lidt om LUA, som også bruger associative arrays som primær datastruktur. Forskellen er primært, at arrays i MUMPS kan være persistente, og at tal repræsenteres som strings.

MUMPS er et imperativt sprog, og har procedurer/funktioner med argumenter og resultatværdier, men ikke mere moderne faciliteter såsom objekter eller funktionelle værdier. Ikke-persistente variabler bruger dynamiske virkefelter (dynamic scoping). Persistente variabler er globale (også på tværs af programmer).

Simpelt men kan være en fordel

MUMPS er alt i alt et relativt simpelt programmeringssprog, men det er ikke nødvendigvis en ulempe. Til kritiske systemer kan det være en fordel, at det er meget klart, hvad der sker (hvilket det ikke altid er, når man kalder virtuelle metoder eller funktionsparametre). MUMPS har dog nogle særheder:

  1. Nøgleord kan forkortes helt ned til enkelte bogstaver. Det skyldes, at MUMPS oprindeligt kørte fortolket og på ret små systemer, men det kan gøre koden svær at læse.

  2. Variabler kan have samme navn som nøgleord. Konteksten gør det klart, om noget er en variabel eller et nøgleord, men det kan igen gøre det svært at læse programmer.

  3. Det er muligt at bygge MUMPS-kode i en string, og bagefter udføre denne. Det kan bruges som erstatning for funktionelle parametre, men det kan gøre det svært at forstå programmer.

  4. Der er ikke noget statisk typesystem, så typefejl findes først under afprøvning.

  5. Dynamiske virkefelter kan også gøre det vanskeligt at følge programlogik.

De to første særheder kan håndteres ved hjælp af automatiske værktøjer, der ekspanderer nøgleord og markerer dem med fed skrift eller farve, så de er nemme at adskille fra variabler. De tre sidste kræver disciplin i programmeringen af systemer, da de ellers kan give anledning til fejl, der er svære at finde.

Er MUMPS så et godt eller skidt sprog til formålet? Det har både gode og dårlige sider, men alt i alt kunne det have været meget værre. Det er ikke voldsomt svært at lære at programmere i MUMPS, og de persistente variabler gør programmering op mod en hierarkisk database nemt og relativt robust. På minussiden kræver de dynamiske egenskaber (scoping, typer og kodeeksekvering) mere disciplin omkring kodestil og afprøvning.

Men umiddelbart er min fornemmelse, at MUMPS ikke er en væsentlig årsag til, at Sundhedsplatformen har problemer. Det skyldes nærmere systemets opbygning og licensbetingelser, samt at processen omkring tilpasning til det danske sundhedssystem og ibrugtagelse har været uigennemtænkt.

Kommentarer (14)
Anne-Marie Krogsbøll

... men kan Mumps alligevel være et problem?
https://thedailywtf.com/articles/A_Case_of_the_MUMPS

Mumps er tydeligvis ikke noget programmører elsker - kan det gøre det svært at holde på gode folk?

I øvrigt ser blogindlægget ud til at være en god og konkret gennemgang af det tekniske - som er langt over mit amatørniveau, men alligevel interessant, så tak for det :-)

Torben Mogensen Blogger

... men kan Mumps alligevel være et problem?
https://thedailywtf.com/articles/A_Case_of_the_MUMPS

Efter historien at dømme, har firmaet gjort alt det, man ikke skal, når man har et dynamisk sprog i stil med MUMPS. De har været (for at bruge et ord fra artiklen) været for "smarte". I et dynamisk sprog skal man kode konservativt og ikke forsøge at bruge de dynamiske faciliteter på en "smart" måde, selv om det på overfladen kan se ud som en gode ide. Og deres navnekonvention . . . Gys.

Lasse Hillerøe Petersen

...over at Perl for nylig blev sablet temmelig meget som sprog, men når det gælder MUMPS er det åbenbart måden det bliver brugt på, der er problemet?

Jeg kan glimrende huske dengang jeg havde fåresyge (det var ret ubehageligt, men jeg var så heldig at kunne låne en DEC Rainbow100, så jeg fornøjede mig med at programmere i Pascal), og når jeg tager et hurtigt kig på RosettaCode eksempler, så ser MUMPS umiddelbart ud til at leve fuldt ud op til sit navn - temmelig sygt og smertefuldt.

Torben Mogensen Blogger

...over at Perl for nylig blev sablet temmelig meget som sprog, men når det gælder MUMPS er det åbenbart måden det bliver brugt på, der er problemet?

MUMPS er langt fra et perfekt sprog, men min pointe var, at det ikke er komplet uegnet til sundheds-IT (det er det faktisk designet til), og at det næppe er valget af sprog, der er skyld i problemerne med Sundhedsplatformen.

Perl er og et fint sprog til dets oprindelige formål -- scripts på 1-5 linjer, der trækker data ud af tekstfiler. Det er når man forsøger at bruge Perl til større systemer, at problemerne opstår.

Yoel Caspersen Blogger

Tak for en fin opsummering af sproget - men selv om sproget i sig selv muligvis er udmærket til formålet, er det så en god ide at kode et stort og omfattende system i et sprog, som anvendes af relativt få programmører?

Jeg tænker her især på risikoen for, at det bliver svært at skaffe gode folk, og at man risikerer vendor lock-in, da man vil have svært ved nogensinde at in-house udviklingen.

Morten Jensen

Hej Yoel,

Jeg kan følge din bekymring, men synes også det er et dilemma. Skal man vælge det sprog der passer bedst til opgaven, eller skal man tage det sprog der er flest udviklere til? I dette tilfælde har man tilsyneladende ikke gjort nogen af delene :D

Nogle projekter skriger efter et (E)DSL, men hospitals-IT kunne nok med fordel udvikles i et mere mainstream sprog.

Carsten Hansen

Er der nogen god begrundelse i dag for, at ikke at have operator-precendence?

Wiki har en omfattende beskrivelse af sproget:
https://en.wikipedia.org/wiki/MUMPS

the statement IF 20<"30 DUCKS" is evaluated as TRUE in MUMPS

Den slags minder om det populære sprog Javascript, som anvendes af alverdens førende it-virksomheder. Måske problemet er, at der mangler Typescript og JSLint. Eller mere relevant i sundhedssektoren Sanitizers som i andre sprog:
https://github.com/google/sanitizers

Klavs Klavsen

Når man vælger sprog - giver det i høj grad også mening at se på om der er delkomponenter/kode-biblioteker man kan anvende til sit system- for derved at spare en masse udvikling - og samtidigt få noget der er velafprøvet og stabilt (hvis man vælger rigtigt :)

Sådanne delkomponenter skal oftest være skrevet i samme sprog som du koder i (medmindre man kan adskille med et API - som f.ex. REST eller andre ældre metoder til det samme) - så her giver det så en binding på valg af sprog.

Torben Mogensen Blogger

selv om sproget i sig selv muligvis er udmærket til formålet, er det så en god ide at kode et stort og omfattende system i et sprog, som anvendes af relativt få programmører?

MUMPS er ikke mere kompliceret end, at en god programmør kan sætte sig ind i det på kort tid, men det kan måske være svært at motivere folk til at sætte sig ind i nye systemer (ikke nødvendigvis kun sprog -- frameworks kan være lige så svære at sætte sig ind i), hvis ikke belønningen er stor. Belønningen kan være kvalifikationer, der kan bruges andre steder, men det er næppe tilfældet her. Så belønningen skal i dette tilfælde nok være i kroner og øre -- eller godt arbejdsmiljø.

Der er mange firmaer, der bruger nichesprog eller selvudviklede sprog, så det kan ikke være umuligt at finde folk til det. Nogle forsikringsselskaber bruger f.eks. GraphTalk, som er en variant af Prolog, der ikke bruges udenfor forsikringsverdenen. Nye folk skal stort set altid på kursus i sproget, men det afholder ikke firmaerne fra at bruge det.

Torben Mogensen Blogger

Er der nogen god begrundelse i dag for, at ikke at have operator-precendence?

Wiki har en omfattende beskrivelse af sproget:
https://en.wikipedia.org/wiki/MUMPS

the statement IF 20<"30 DUCKS" is evaluated as TRUE in MUMPS

Den slags minder om det populære sprog Javascript, som anvendes af alverdens førende it-virksomheder. Måske problemet er, at der mangler Typescript og JSLint. Eller mere relevant i sundhedssektoren Sanitizers som i andre sprog.

Jeg ville personligt ikke designe et sprog uden operatorpræcedens for de almindelige aritmetiske operatorer -- med mindre jeg brugte LISP-agtig syntaks, så det ovenstående ville skrives som (* (+ 2 3) 10). Det er dog ikke uhørt. F.eks. har APL heller ikke operatorpræcedens. For APL giver det god mening, da antallet af operatorer er så stort, at det vil være meget svært at huske præcedens for alle. Så er det klart nemmere ikke at have nogen.

Implicitte konverteringer (som i eksemplet med 20<"30 DUCKS") ville jeg heller ikke selv vælge, men som Carsten siger, så findes de også i f.eks. Javascript, som er særdeles udbredt. Både manglen på præcedens og implicitte konverteringer kræver ekstra kodedisciplin og test. Jeg ville personligt sætte parenteser i regneudtrykket, så det blev (2+3)*10, for at gøre det tydeligt, hvordan bindingen er.

Jeg ved ikke, om der findes sanitizers til MUMPS, men det vil klart være en god ide. Jeg nævnte selv ekspandering af forkortede nøgleord som et oplagt sted at bruge automatiske værktøjer.

Log ind eller Opret konto for at kommentere