Why Not Rust? The Web Community Questions TypeScript's Decision
Rust, as a systems programming language, has gained an exceptional reputation in web development in recent years. It is known for its memory safety, high performance, and concurrent processing capabilities, which give Rust significant advantages in developing efficient and reliable web applications. Particularly in WebAssembly (WASM), Rust has demonstrated outstanding performance and applicability.
WebAssembly is an emerging web standard designed to provide near-native performance execution environments for web applications. The combination of Rust and WebAssembly enables developers to write efficient, secure web components that can run in browsers at near-native speeds. This capability has made Rust highly regarded in the web development community, with many developers questioning "why not Rust?" when they learned about the TypeScript team's decision.
However, despite Rust's excellent performance in WebAssembly, the TypeScript team chose Golang over Rust when porting TypeScript 7. This decision to create TypeScript Go involved multiple considerations, including technical feasibility, development efficiency, and long-term maintenance costs.
TypeScript Go: Porting Rather Than Rewriting
The TypeScript team clearly stated that porting TypeScript 7 to Golang (creating what some are calling "TypeScript Go") is a "port" rather than a "rewrite." The core of this decision is to preserve the structure and semantics of the existing codebase as much as possible, ensuring high compatibility with the original TypeScript version while improving performance and development efficiency.
Similarity in Code Structure
TypeScript's existing codebase adopts a primarily functional programming style, rarely using object-oriented features like classes. Golang, as a concise and efficient programming language, has a design philosophy that highly aligns with TypeScript's existing code structure. Centered on functions and data structures, Golang emphasizes code readability and simplicity, making it relatively easy to maintain the original code logic and structure when porting TypeScript code to Golang.
Advantages in Memory Management
Golang has built-in automatic garbage collection (GC), which provides great convenience for developers. In projects like the TypeScript compiler that handle numerous memory operations, automatic memory management significantly reduces development complexity and potential memory leak issues. In contrast, while Rust excels in memory safety, it lacks automatic garbage collection and requires manual memory management, which adds substantial development workload and code complexity when dealing with complex cyclic data structures and dynamic memory allocation.
Developer Experience Considerations
In terms of developer experience, Golang also shows clear advantages. Golang's error handling mechanism is more similar to TypeScript's try/catch
pattern, allowing developers to transition more naturally during the porting process. Additionally, Golang's interface system is highly compatible with TypeScript's structural type system, which helps maintain code consistency and maintainability.
Why Not Rust? Trade-offs in the TypeScript Go Decision
Despite Rust's excellent performance in performance and memory safety, it is not the best choice for porting TypeScript to a native language. The TypeScript Go team conducted in-depth trade-off considerations during the decision-making process, involving several key factors.
Balance Between Performance and Development Experience
In performance tests, the Golang-ported version of TypeScript performed similarly to the Rust experimental version in cold start time, incremental compilation speed, memory peak, and concurrent task throughput, with the Golang version even showing advantages in some metrics. However, to achieve high performance with Rust, developers often need to use a lot of unsafe code and require fine control over memory management and lifetimes. This not only increases code complexity but may also lead to longer development cycles and higher maintenance costs.
Challenges in Handling Cyclic Data Structures
The TypeScript compiler heavily relies on cyclic data structures, such as abstract syntax trees (ASTs) with parent-child references and mutually referencing symbols and declarations. Rust's strict limitations on cyclic data structures require significant adjustments and refactoring during the porting process, undoubtedly increasing the difficulty and risk of porting. Golang is more flexible in handling such data structures and can better adapt to TypeScript's original code logic.
Long-term Maintenance and Evolution Costs
From the perspective of long-term maintenance and evolution, choosing Golang also has certain advantages. Golang has a powerful standard library and rich ecosystem that can provide good support for TypeScript projects. Additionally, Golang's concurrency model (goroutines and channels) highly aligns with the potential parallelization needs of the TypeScript compiler, providing possibilities for further performance optimization in the future.
In conclusion, when porting TypeScript 7 to Golang to create TypeScript Go, the TypeScript team comprehensively considered the web community's advocacy for Rust, the frequent questions of "why not Rust?", and various trade-off factors. This decision not only reflects a profound understanding of technical feasibility and development efficiency but also a comprehensive consideration of the project's long-term development and maintenance costs. As TypeScript Go continues to develop and optimize on Golang, we have reason to believe it will continue to play an important role in future web development, bringing developers a more efficient and higher-quality programming experience.
Code and life are the art of trade-offs; choosing what suits you best is the best choice.