- TypeScript-teamet valgte en port for å gå over en fullstendig omskriving for å holde feilmeldinger og semantikk identisk.
- Gos søppelinnsamling og førsteklasses lukkinger var avgjørende for å håndtere kompilatorens komplekse datastrukturer.
- Rusts lånekontrollør ville ha tvunget frem manuelle løsninger for sirkelreferanser, noe som ville gjort det unødvendig komplisert.
- Go sørget for generering av moden, innebygd kode og samtidighet i delt minne uten ekstra innsats.

Da TypeScript-teamet bestemte seg for å portere kompilatoren sin til et nytt språk, hadde de et klart mål: å holde alt i gang akkurat som før. Det betydde å bevare de nøyaktige feilmeldingene og semantikken som utviklere har vært avhengige av i årevis. Ifølge Anders Hejlsberg, hovedarkitekten, var en fullstendig omskriving utelukket fordi det ville risikere å bryte bakoverkompatibiliteten. I stedet valgte de en portering – og den avgjørelsen la grunnlaget for et overraskende valg: Gå over Rust.
Porteringen trengte et språk som kunne håndtere kompilatorens intrikate interne strukturer uten å tvinge frem store endringer. Teamet innså raskt at søppelinnsamling og førsteklasses nedleggelser ikke var noe å forhandle om. Go tilbyr begge deler rett ut av boksen, sammen med moden, native kodegenerering og samtidighet i delt minne på alle større plattformer. Rust, derimot, ville ha krevd betydelige manuelle løsninger, spesielt for kompilatorens sirkulære datastrukturer.
Hvorfor gå over rust for havnen
Hejlsberg forklarte at kompilatoren er full av foreldrepekere, rekursive typer og symboler som refererer til hverandre. Disse skaper sirkulære referanser som er naturlige i et språk med søppelinnsamling. Gos runtime håndterer dette sømløst, slik at teamet kan fokusere på porteringen i stedet for å kjempe mot språket. Rusts lånekontroll, selv om den er kraftig for minnesikkerhet, tillater rett og slett ikke den formen uten å ty til usikker kode eller referansetellingstriks. Det ville øke kompleksiteten og risikoen, uten noen klar uttelling.
Da teamet sammenlignet de to språkene, fant de ingen signifikant fordel i kodegenerering eller samtidighet for Rust. Gos innebygde kodegenerering er allerede moden, og goroutinene gir en enkel og effektiv modell for samtidig utførelse. Rusts ytelse kan være litt bedre i noen edge-tilfeller, men den ekstra innsatsen som kreves for å få kompilatoren til å fungere med eierreglene, var ikke berettiget. Porteringen måtte være pragmatisk, ikke et utstillingsvindu for språkfunksjoner.
Kompatibilitet og semantikk: Toppprioritet
Den primære drivkraften bak porteringen var å opprettholde identisk oppførsel. Utviklere er avhengige av TypeScripts feilmeldinger for å feilsøke koden sin, og enhver endring kan ødelegge arbeidsflytene deres. Ved å portere til Go kunne teamet gjenbruke eksisterende logikk og datastrukturer, og sikre at utdataene forblir byte-for-byte-kompatibele. Denne tilnærmingen reduserer også risikoen for å introdusere subtile feil som en omskriving kan medføre.
Gos søppeltømming var en viktig muliggjører. Kompilatorens interne graf over noder og referanser er sterkt sammenkoblet, og manuell minnehåndtering ville vært et mareritt. Med Go kan teamet allokere og frigjøre minne automatisk, slik at de kan fokusere på kompilatorens logikk. Førsteklasses lukkinger gjorde det også enklere å implementere de ulike passeringene og transformasjonene som kompilatoren utfører, ettersom de kan fange opp kontekst naturlig.
Rusts lånesjekker: En avtalebryter
Rusts lånekontroll er designet for å forhindre datakappløp og minnefeil ved kompilering, men den kommer med strenge regler. TypeScript-kompilatorens datastrukturer er fulle av sykluser og delte referanser, som lånekontrollen avviser med mindre du bruker usikre blokker eller Rc/RefCell. Hejlsberg bemerket at dette ville tvinge frem manuelle løsninger for hver sirkulære datastruktur, legge til standardinnstillinger og gjøre koden vanskeligere å vedlikeholde. Det var ingen kodegenererings- eller samtidighetsfordel som rettferdiggjorde det ekstra arbeidet.
Til slutt var valget klart. Go tilbød den rette balansen mellom enkelhet, ytelse og kompatibilitet. Porteringen er nå i gang, og teamet er sikre på at den vil levere den samme TypeScript-opplevelsen med en raskere og mer effektiv kompilator. For utviklere betyr dette ingen overraskelser – bare det samme pålitelige verktøyet de alltid har brukt, som kjører på et mer moderne grunnlag.
Alt i alt handler beslutningen om å velge Go over Rust for TypeScript-porten om praktisk ingeniørkunst. Behovet for søppeltømming, førsteklasses lukkinger og sømløs håndtering av sirkulære referanser gjorde Go til det naturlige valget. Rusts sikkerhetsgarantier er imponerende, men de kommer til en pris som TypeScript-teamet ikke var villige til å betale. Resultatet er en port som bevarer alt utviklerne elsker med TypeScript, samtidig som den legger grunnlaget for fremtidige forbedringer.