- Tým TypeScript si vybral port, který bude kompletně přepsán, aby chybové zprávy a sémantika zůstaly identické.
- Sběr odpadků a prvotřídní uzávěry jazyka Go byly nezbytné pro zpracování složitých datových struktur kompilátoru.
- Kontrola půjček v Rustu by vynutila ruční řešení cyklických referencí, což by zbytečně zvyšovalo složitost.
- Go poskytoval vyspělé generování nativního kódu a souběžnost ve sdílené paměti bez jakéhokoli dalšího úsilí.

Když se tým TypeScript rozhodl portovat svůj kompilátor do nového jazyka, měl jasný cíl: zachovat funkčnost všech chybových hlášení a sémantiky, na které se vývojáři spoléhali po celá léta. Podle Anderse Hejlsberga, hlavního architekta, nebylo možné kompletní přepracování programu možné, protože by riskovalo narušení zpětné kompatibility. Místo toho se rozhodli pro port – a toto rozhodnutí připravilo půdu pro překvapivou volbu: přejít na Ruste.
Port potřeboval jazyk, který by zvládl složité vnitřní struktury kompilátoru, aniž by vynucoval zásadní změny. Tým si rychle uvědomil, že garbage collection a prvotřídní uzávěry jsou nezbytné. Go nabízí obojí ihned po instalaci, spolu s vyspělým generováním nativního kódu a souběžností ve sdílené paměti na všech hlavních platformách. Rust by na druhou stranu vyžadoval značná manuální řešení, zejména pro cyklické datové struktury kompilátoru.
Proč se pro port vyplatí jít přes Rust
Hejlsberg vysvětlil, že kompilátor je plný ukazatelů na rodiče, rekurzivních typů a symbolů, které se na sebe navzájem odkazují. Ty vytvářejí cyklické odkazy, které jsou v jazyce s garbage collection přirozené. Runtime prostředí Go to zvládá bez problémů, což umožňuje týmu soustředit se na port, spíše než bojovat s jazykem. Kontrola vypůjčených odkazů v Rustu, ačkoli je výkonná pro bezpečnost paměti, tento tvar jednoduše neumožňuje, aniž by se muselo uchýlit k nebezpečnému kódu nebo trikům s počítáním odkazů. To by přidalo složitost a riziko, bez jasného přínosu.
Při porovnání obou jazyků tým nenalezl žádnou významnou výhodu Rustu v generování kódu nebo souběžnosti. Nativní generování kódu v Go je již vyspělé a jeho gorutiny poskytují jednoduchý a efektivní model pro souběžné provádění. Výkon Rustu může být v některých okrajových případech o něco lepší, ale dodatečné úsilí potřebné k tomu, aby kompilátor fungoval s jeho pravidly vlastnictví, nebylo opodstatněné. Port musel být pragmatický, ne přehlídka jazykových funkcí.
Kompatibilita a sémantika: Nejvyšší priorita
Hlavním důvodem portování bylo zachování identického chování. Vývojáři se při ladění kódu spoléhají na chybové zprávy TypeScriptu a jakákoli změna by mohla narušit jejich pracovní postupy. Portováním na Go by tým mohl znovu použít stávající logiku a datové struktury, čímž by se zajistila kompatibilita výstupu bajt po bajtu. Tento přístup také snižuje riziko vzniku drobných chyb, které by přepisování mohlo přinést.
Sběr odpadků v Go byl klíčovým faktorem. Vnitřní graf uzlů a referencí kompilátoru je vysoce propojený a ruční správa paměti by byla noční můrou. S Go může tým automaticky alokovat a uvolňovat paměť, což mu umožňuje soustředit se na logiku kompilátoru. Prvotřídní uzávěry také usnadňují implementaci různých průchodů a transformací, které kompilátor provádí, protože dokáží přirozeně zachytit kontext.
Rustův Borrow Checker: Překonávání obchodů
Kontrola převodů v Rustu je navržena tak, aby zabránila datovým závodům a chybám v paměti během kompilace, ale má přísná pravidla. Datové struktury kompilátoru TypeScript jsou plné cyklů a sdílených odkazů, které kontrola převodů odmítá, pokud nepoužíváte nebezpečné bloky nebo Rc/RefCell. Hejlsberg poznamenal, že by to vynutilo ruční řešení pro každou kruhovou datovou strukturu, což by přidalo standardizovaný kód a ztížilo údržbu kódu. Neexistovala žádná výhoda generování kódu ani souběžnosti, která by ospravedlňovala tuto dodatečnou práci.
Nakonec byla volba jasná. Go nabízel správnou rovnováhu mezi jednoduchostí, výkonem a kompatibilitou. Portování je nyní v plném proudu a tým je přesvědčen, že nabídne stejný zážitek z TypeScriptu s rychlejším a efektivnějším kompilátorem. Pro vývojáře to znamená žádná překvapení – jen stejný spolehlivý nástroj, který vždy používali, běžící na modernějším základě.
Celkově vzato se rozhodnutí zvolit Go místo Rustu pro port TypeScriptu v podstatě svádí na praktické inženýrství. Potřeba garbage collection, prvotřídních uzávěrů a bezproblémového zpracování cyklických referencí učinila z Go přirozenou volbu. Bezpečnostní záruky Rustu jsou působivé, ale přicházejí za cenu, kterou tým TypeScriptu nebyl ochoten zaplatit. Výsledkem je port, který zachovává vše, co vývojáři na TypeScriptu milují, a zároveň pokládá základy pro budoucí vylepšení.