- TypeScript komanda izvēlējās portu, lai veiktu pilnīgu pārrakstīšanu, lai kļūdu ziņojumi un semantika būtu identiski.
- Go atkritumu savākšana un pirmās klases slēgšanas bija būtiskas kompilatora sarežģīto datu struktūru apstrādei.
- Rust aizņēmumu pārbaudītājs būtu piespiedis manuālus risinājumus apļveida atsaucēm, radot nevajadzīgu sarežģītību.
- Go nodrošināja nobrieduša vietējā koda ģenerēšanu un koplietotās atmiņas vienlaicīgumu bez papildu piepūles.

Kad TypeScript komanda nolēma pārnest savu kompilatoru uz jaunu valodu, viņiem bija skaidrs mērķis: nodrošināt, lai viss darbotos tieši tāpat kā iepriekš. Tas nozīmēja saglabāt tieši tos pašus kļūdu ziņojumus un semantiku, uz ko izstrādātāji bija paļāvušies gadiem ilgi. Pēc galvenā arhitekta Andersa Heilsberga teiktā, pilnīga pārrakstīšana nebija iespējama, jo tā riskētu pārkāpt atpakaļejošo saderību. Tā vietā viņi izvēlējās pārnesi, un šis lēmums radīja pamatu pārsteidzošai izvēlei: atteikties no Rust.
Portam bija nepieciešama valoda, kas spētu apstrādāt kompilatora sarežģītās iekšējās struktūras, nepiespiežot veikt būtiskas izmaiņas. Komanda ātri saprata, ka atkritumu savākšana un pirmās klases slēgšana nav apspriežami. Go piedāvā abus uzreiz pēc instalēšanas, kā arī nobrieduša vietējā koda ģenerēšanu un koplietotas atmiņas vienlaicīgumu visās galvenajās platformās. Savukārt Rust būtu prasījis ievērojamus manuālus risinājumus, īpaši kompilatora apļveida datu struktūrām.
Kāpēc ostas labā pāriet uz rūsu
Heilsbergs paskaidroja, ka kompilators ir pilns ar vecāku rādītājiem, rekursīviem tipiem un simboliem, kas atsaucas viens uz otru. Tie rada apļveida atsauces, kas ir dabiskas valodā ar atkritumu savākšanu. Go izpildlaiks ar to tiek galā nemanāmi, ļaujot komandai koncentrēties uz portu, nevis cīnīties ar valodu. Rust aizņemšanās pārbaudītājs, lai gan ir spēcīgs atmiņas drošības ziņā, vienkārši nepieļauj šādu formu, neizmantojot nedrošu kodu vai atsauču skaitīšanas trikus. Tas palielinātu sarežģītību un risku, bez skaidras atdeves.
Salīdzinot abas valodas, komanda neatrada būtiskas priekšrocības Rust koda ģenerēšanā vai vienlaicīgumā. Go vietējā koda ģenerēšana jau ir nobriedusi, un tās gorutīnas nodrošina vienkāršu un efektīvu modeli vienlaicīgai izpildei. Rust veiktspēja dažos perifēriskajos gadījumos varētu būt nedaudz labāka, taču papildu pūles, kas nepieciešamas, lai kompilators darbotos ar tā īpašumtiesību noteikumiem, nebija pamatotas. Portam bija jābūt pragmatiskam, nevis valodas funkciju demonstrēšanai.
Saderība un semantika: galvenā prioritāte
Galvenais pārneses iemesls bija identiskas darbības saglabāšana. Izstrādātāji paļaujas uz TypeScript kļūdu ziņojumiem, lai atkļūdotu savu kodu, un jebkuras izmaiņas varētu traucēt viņu darbplūsmas. Pārnesot uz Go, komanda varētu atkārtoti izmantot esošo loģiku un datu struktūras, nodrošinot, ka izvade saglabā baits pa baitam saderību. Šī pieeja arī samazina nelielu kļūdu ieviešanas risku, ko varētu radīt pārrakstīšana.
Go atkritumu savākšana bija galvenais faktors. Kompilatora iekšējais mezglu un atsauču grafs ir ļoti savstarpēji saistīts, un manuāla atmiņas pārvaldība būtu murgs. Ar Go komanda var automātiski piešķirt un atbrīvot atmiņu, ļaujot viņiem koncentrēties uz kompilatora loģiku. Pirmklasīgas slēgšanas metodes arī atviegloja dažādu kompilatora veikto pāreju un transformāciju ieviešanu, jo tās var dabiski uztvert kontekstu.
Rust's Borrow Checker: Darījumu lauzējs
Rust aizņemšanās pārbaudītājs ir izstrādāts, lai novērstu datu sacensības un atmiņas kļūdas kompilēšanas laikā, taču tam ir stingri noteikumi. TypeScript kompilatora datu struktūras ir pilnas ar cikliem un koplietotām atsaucēm, kuras aizņemšanās pārbaudītājs noraida, ja vien netiek izmantoti nedroši bloki vai Rc/RefCell. Hejlsbergs atzīmēja, ka tas piespiestu manuālus risinājumus katrai apļveida datu struktūrai, pievienojot standarta veidni un apgrūtinot koda uzturēšanu. Nebija nekādu koda ģenerēšanas vai vienlaicības priekšrocību, kas attaisnotu šo papildu darbu.
Galu galā izvēle bija skaidra. Go piedāvāja pareizo vienkāršības, veiktspējas un saderības līdzsvaru. Ports pašlaik ir izstrādes procesā, un komanda ir pārliecināta, ka tas nodrošinās tādu pašu TypeScript pieredzi, bet ar ātrāku un efektīvāku kompilatoru. Izstrādātājiem tas nozīmē nekādus pārsteigumus — tikai to pašu uzticamo rīku, ko viņi vienmēr ir izmantojuši, kas darbojas uz modernākas platformas.
Ņemot vērā visus apstākļus, lēmums TypeScript portam izvēlēties Go, nevis Rust, ir saistīts ar praktiskiem inženiertehniskiem apsvērumiem. Nepieciešamība pēc atkritumu savākšanas, pirmklasīgām slēgšanas iespējām un nemanāmas apļveida atsauču apstrādes padarīja Go par dabisku izvēli. Rust drošības garantijas ir iespaidīgas, taču tās maksā dārgi, ko TypeScript komanda nebija gatava maksāt. Rezultāts ir ports, kas saglabā visu, kas izstrādātājiem patīk TypeScript, vienlaikus liekot pamatu turpmākiem uzlabojumiem.