Anders Hejlsberg Rewrites TypeScript Compiler in Go

Creator of TypeScript: 10x Faster Typescript, Why AI Won't Replace SWEs | Anders Hejlsberg — Ryan Peterman

Ryan Peterman

TypeScript achieved a tenfold performance boost by rewriting its compiler in Go because JavaScript's single-threaded event loop and memory model imposed an unavoidable execution bottleneck.

AI-assisted summary of Creator of TypeScript: 10x Faster Typescript, Why AI Won't Replace SWEs | Anders Hejlsberg — original source. Check the original for full context.

Source published:

Key ideas

  • The TypeScript compiler achieved a 10x performance improvement by undergoing a native rewrite in Go, enabling shared-memory concurrency across multiple CPU cores to overcome single-threaded JavaScript performance limits. (7:29)
  • Go was selected over Rust because the TypeScript compiler relies heavily on cyclic reference graphs between AST nodes and symbol tables, making automatic garbage collection mandatory without completely redesigning internal memory models. (12:16)
  • For the 500,000 to 1,000,000-line compiler migration, the team built a deterministic syntactic transpiler rather than relying on bulk LLM translation, avoiding the unsustainable burden of auditing hallucinated bugs across massive codebases. (14:49)
  • The rise of autonomous coding agents makes fast compiler tooling even more critical, as machines invoke semantic type checking and refactoring tools far more frequently than humans, turning latency into the primary bottleneck. (49:14)

Detailed notes

## Background This interview was published by Ryan Peterman on YouTube on August 17, 2026. According to the show description, it features programming language pioneer Anders Hejlsberg discussing how the TypeScript compiler achieved a 10x performance boost through a native rewrite in Go, alongside his perspective on how AI is shaping software engineering.

## TL;DR Anders Hejlsberg breaks down the engineering rationale behind migrating the TypeScript compiler from JavaScript to Go, explaining how single-threaded runtime bottlenecks, cyclic graph data structures, and the end of single-core Moore's Law made Go the ideal target over Rust while ruling out backward-incompatible greenfield rewrites. He details their migration strategy using a deterministic syntactic transpiler rather than raw LLMs, warning against relying on stochastic tools for bulk rewrites. Hejlsberg also evaluates the practical impact of AI, arguing that while agents will generate vast amounts of scaffolding and demand ultra-fast compiler feedback loops, human engineers remain essential for system comprehension, novel architectures, and real-world legal and business accountability. Finally, he shares lessons from his decades-long career, emphasizing the value of staying a hands-on coder over becoming an detached 'architecture astronaut.'

## Atmosphere & style The conversation carries the warm, grounded, and deeply pragmatic tone of a veteran systems craftsman reflecting on four decades at the frontier of compiler design. Host Ryan Peterman maintains a relaxed, curious interview dynamic, allowing Hejlsberg to fluidly connect foundational war stories—like hand-optimizing Z80 assembly jumps for Turbo Pascal—with bleeding-edge modern concurrency and AI agent pipelines. Listening to Hejlsberg feels refreshingly authentic and invigorating; his obvious joy for simply opening an editor with a morning coffee cuts through contemporary industry hype with clarity and common sense.

## Bulletin - [07:29](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=449s) The TypeScript compiler achieved a 10x performance improvement by undergoing a native rewrite in Go, enabling shared-memory concurrency across multiple CPU cores to overcome single-threaded JavaScript performance limits. - [12:16](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=736s) Go was selected over Rust because the TypeScript compiler relies heavily on cyclic reference graphs between AST nodes and symbol tables, making automatic garbage collection mandatory without completely redesigning internal memory models. - [14:49](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=889s) For the 500,000 to 1,000,000-line compiler migration, the team built a deterministic syntactic transpiler rather than relying on bulk LLM translation, avoiding the unsustainable burden of auditing hallucinated bugs across massive codebases. - [49:14](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=2954s) The rise of autonomous coding agents makes fast compiler tooling even more critical, as machines invoke semantic type checking and refactoring tools far more frequently than humans, turning latency into the primary bottleneck.

## Key takeaways - [00:48](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=48s) Writing the initial TypeScript compiler in JavaScript enabled universal cross-platform execution and browser-based self-hosting before WebAssembly existed. - [07:29](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=449s) The end of single-thread CPU frequency scaling and the lack of shared-memory concurrency in JavaScript made native multi-core execution essential for massive enterprise codebases. - [12:16](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=736s) Rust's borrow checker and lack of built-in garbage collection made it ill-suited for a direct port of TypeScript's cyclic AST and recursive type structures. - [14:49](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=889s) Large codebase migrations benefit from deterministic transpilation to bridge syntax differences while restricting LLMs to targeted, localized tasks like test generation and triage. - [19:17](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1157s) Clean-slate greenfield rewrites frequently harm developer ecosystems by introducing subtle semantic drifts and breaking downstream backwards compatibility. - [23:28](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1408s) Extensive training data creates a compounding advantage for incumbent languages like JavaScript, TypeScript, and Python, making it increasingly difficult for new languages to gain AI tooling traction. - [23:28](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1408s) Static type systems significantly improve AI code generation by creating immediate compiler diagnostic feedback loops that eliminate hallucinations. - [28:26](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1706s) Sophisticated language features such as discriminated unions and control-flow analysis halved TypeScript's baseline processing speed over time, compounding scaling bottlenecks. - [47:10](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=2830s) TypeScript succeeded over alternative projects by enhancing JavaScript directly and prioritizing editor language services from day one rather than treating JavaScript purely as a compilation target. - [49:14](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=2954s) Sub-second compiler feedback is required to support AI agents, which cannot reliably use text search across large codebases and rely on LSP interfaces for semantic refactoring. - [51:16](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3076s) While LLMs excel at generating boilerplate and scaffolding, they struggle with novel algorithmic design and cannot replace the legal accountability and comprehension provided by human engineers. - [56:04](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3364s) The software engineering discipline is increasingly shifting toward agent steering and code review, highlighting the critical need to preserve training paths for junior engineers. - [58:52](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3532s) Retrofitting a sequential compiler pipeline into a safe, shared-memory concurrent model across all CPU cores was the most complex technical hurdle of the native rewrite. - [01:02:05](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3725s) Niklaus Wirth's 'Algorithms + Data Structures = Programs' established core compiler construction principles, emphasizing pragmatic data structures like hash tables over dense mathematical formalism.

## Detailed walkthrough ### [00:00](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=0s) Episode Teaser: Compiler Rewrites and AI Skepticism

The episode opens with Anders Hejlsberg offering a punchy piece of philosophy: "Don't let people tell you that it can't be done. When they tell you it can't be done, it's because *they* can't do it." As the legendary designer of C# and TypeScript, Hejlsberg previews the central theme of the conversation: the major engineering initiative to rebuild the TypeScript compiler natively, resulting in a dramatic 10x performance improvement.

The teaser touches on several controversial questions that define contemporary software engineering. Hejlsberg and host Ryan Peterman banter about whether it would have been better to simply "fix JavaScript," the technical tradeoffs that led the team away from Rust toward Go, and the current fever pitch surrounding artificial intelligence. When asked about differing viewpoints from AI labs like Anthropic, Hejlsberg expresses clear skepticism toward total automation: "People love these like take it all the way to 100%, right? And that's where I get off the bus."

---

[00:48](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=48s) Why the TypeScript Compiler Was Originally Written in JavaScript

Ryan opens the main discussion by addressing the surprising origins of the TypeScript compiler: it was implemented entirely in JavaScript. Compilers are traditionally written in low-level, statically typed systems languages like C or C++, making a high-level dynamic language seem like an unorthodox choice. Hejlsberg admits that had anyone told him before TypeScript launched that he would spend years building compilers in JavaScript, he would have flatly refused. The very first prototype, an internal Microsoft project codenamed "Strata," was actually implemented in C by adapting the JavaScript parser from Internet Explorer. However, the team deliberately chose to move the codebase to JavaScript, authoring it in a structured C style before migrating it to TypeScript itself.

The primary motivation was the immense leverage gained from self-hosting directly within the target ecosystem. By writing the compiler in TypeScript, the engineering team became their own daily users. Every bug, slow edge case, and tooling deficiency was felt immediately by the team building the language. Placing the implementation outside the JavaScript world would have severed that tight feedback loop. Universal reach was another deciding factor: JavaScript executed on every platform out of the box, including directly inside web browsers—a feat that native binaries could not accomplish in the era before WebAssembly existed.

Finally, JavaScript runtime performance had quietly undergone a revolution. Google's work on the V8 engine closed the gap with native execution down to roughly 2x to 3x, proving that a complex compiler was entirely viable in a dynamic runtime if paired with disciplined algorithms. As Hejlsberg highlights, execution speed is fundamentally governed by algorithmic design rather than runtime mechanics alone.

- The original TypeScript prototype was called the "Strata" project and repurposed the Internet Explorer C-based JavaScript parser. - Self-hosting within the target ecosystem provided instantaneous dogfooding for compiler bugs and developer tooling performance. - JavaScript allowed the compiler to run universally across platforms and in-browser prior to the advent of WebAssembly. - Google V8 brought JavaScript execution within a 2x to 3x performance envelope of native machine code.

---

[03:38](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=218s) What Makes the TypeScript Compiler Unique

The TypeScript compiler fundamentally diverges from classical toolchains like Clang or GCC in its execution target and the role of its type system. Traditional native compilers ingest high-level source code to emit optimized machine instructions. By contrast, TypeScript emits JavaScript, operating primarily as a transpiler. In its early days, an essential responsibility of the compiler was "downleveling" modern ECMAScript features for older, non-evergreen browsers—such as converting ES6 classes into compatible ES5 constructor functions. Over time, as runtimes standardized and adopted modern specs natively, this downlevel transformation became secondary.

```mermaid flowchart TD accTitle: Traditional Compiler vs TypeScript Architecture accDescr: Diagram contrasting traditional compiler pipelines with TypeScript's type-erasure and tooling-centric pipeline.

subgraph TRAD["Traditional Compiler Pipeline (e.g., Clang)"] TC1["Source Code"] --> TC2["Type Checking"] TC2 -->|"Types Guide Codegen"| TC3["Optimization Passes"] TC3 --> TC4["Machine Code / Binary"] end

subgraph TS["TypeScript Compiler Pipeline"] TSC1["TypeScript Source"] --> TSC2["Gradual Type Checker"] TSC2 -.->|"Diagnostics & AST Info"| TSC3["Tooling & Language Server"] TSC3 --> TSC4["Autocomplete / Refactor / Nav"] TSC1 --> TSC5["Type Erasure & Downleveling"] TSC5 --> TSC6["Standard JavaScript Output"] end ```

The most striking architectural difference lies in TypeScript's type checker. In conventional compilers, types dictate machine code generation—the compiler must know whether a value is a float, integer, or string to select the correct CPU instructions. In TypeScript, types have absolutely zero runtime manifestation. Because the compilation step strips all type annotations away, types cannot alter runtime behavior. Instead, the type system exists exclusively as a developer productivity tool to power autocompletion, refactoring, and code navigation.

Furthermore, TypeScript implements a pragmatic "gradual type system," allowing developers to leave portions of their codebase completely unchecked using the `any` escape hatch. The compiler also intentionally foregoes typical machine optimizations like loop unrolling or dead instruction elimination. Many modern projects bypass TypeScript's code emitter altogether, relying on high-speed native bundlers such as esbuild or SWC to strip types while utilizing TypeScript solely as a diagnostic type engine.

- **Type Erasure:** Types have zero impact on runtime behavior and are completely erased during emit. - **Downleveling:** Transpiled modern syntax down to older ECMAScript standards (e.g., turning classes into prototype constructor functions). - **Tooling Focus:** Type checking serves the IDE experience (statement completion, refactoring, code navigation) rather than instruction selection. - **Gradual Typing:** Code can mix strict static types with unchecked `any` values. - **Ecosystem Integration:** Modern workflows frequently pair TypeScript's type checking with native bundlers like esbuild or SWC for asset packaging.

---

[07:29](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=449s) The Limits of JavaScript and the Decision to Move to Native Code

When asked why the team decided to pursue the major native rewrite for TypeScript 7, Hejlsberg points directly to performance and scalability limits. JavaScript was fundamentally engineered to build user interfaces in web browsers—a domain originally conceived for roughly a hundred lines of script—rather than compute-heavy, memory-intensive infrastructure like static language analyzers. Under heavy computational workloads, JavaScript carries an unavoidable 2x to 3x execution penalty compared to native machine instructions.

The more fatal obstacle, however, was concurrency. JavaScript was architected from the ground up as a single-threaded runtime relying on an asynchronous event loop, promises, and callbacks to avoid the perils of mutable shared-state race conditions and deadlocks. While modern web workers allow parallel execution, they maintain isolated memory spaces. Sharing data between workers requires serialization—typically remoting objects back and forth through JSON—preventing workers from sharing in-memory data structures directly.

As Moore's Law stopped delivering faster single-core clock speeds and shifted hardware scaling toward multi-core CPUs, TypeScript was effectively blocked from exploiting modern hardware:

> "Moore's Law has stopped giving us faster CPUs. It's giving us more CPUs, and we got to like find ways to use them in our compute-intensive workloads or else we're leaving money on the table."

To capture that unexploited performance, TypeScript needed a native runtime equipped with true shared-memory concurrency. When asked why the team chose Go over popular modern systems languages like Rust or Zig, Hejlsberg clarifies their foundational strategy: the project was never conceived as a greenfield rewrite, but rather as an exact, faithful port of the existing compiler logic.

- Compute workloads in JavaScript suffer an inherent 2x to 3x performance penalty against native binaries. - Web workers lack shared memory; cross-thread communication requires expensive object serialization (such as JSON). - The end of Moore's Law single-thread scaling mandates multi-core concurrency to handle enterprise-scale codebases. - The TypeScript team chose Go over Rust or Zig through a disciplined evaluation focused on porting rather than redesigning from scratch.

[10:48](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=648s) Choosing Go: Matching the Existing TypeScript Architecture

Preserving the exact semantics, algorithms, and observable behavior of the existing TypeScript compiler was an absolute prerequisite for the team. Because millions of developers and enterprise codebases depend on TypeScript for backwards compatibility, starting with a clean slate from scratch was out of the question. A ground-up rewrite would inevitably produce a subtly different language—one that would issue different error diagnostics or make different resolution choices when disambiguating between multiple possibilities.

The decision to port rather than redesign meant the target language had to support the fundamental architectural assumptions already baked into the TypeScript codebase. Specifically, the compiler relied heavily on automatic garbage collection and first-class functions that support lexical closures—nested functions capable of capturing and closing over outer state. When the team evaluated candidates against these strict constraints, Go emerged as the clear winner. Go provided mature, robust native code generation across all major target platforms, native garbage collection, and outstanding shared-memory concurrency primitives out of the box. Every other evaluated language had friction points that directly undermined those core requirements.

- Core architectural dependencies in the TypeScript compiler: - Reliance on automatic garbage collection. - First-class nested functions with lexical scoping and closure state capture. - Shared-memory concurrency across threads. - High-performance, mature native binaries across Windows, macOS, and Linux.

---

[12:16](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=736s) Why Rust Failed the Test: The Circular Reference Problem

When asked why Rust was passed over, Anders explains that Rust lacked two critical attributes required for a direct port: native garbage collection and native ergonomics for circular reference graphs. Rust avoids garbage collection via its borrow checker, but the borrow checker fundamentally resists cyclic data structures. The TypeScript compiler's internal memory graph is completely saturated with circular structures: abstract syntax trees with parent pointers, recursive and mutually referential types, and complex symbol tables pointing back and forth across scopes.

```mermaid flowchart TD accTitle: TypeScript Compiler Internal Graph Complexity accDescr: Diagram showing cyclic dependencies between AST nodes, types, and symbols that broke Rust's borrow checker.

subgraph MemoryGraph["Cyclic Internal Compiler Structures"] AST["AST Node"] Parent["Parent Pointer"] Type["Recursive Type"] Symbol["Symbol Table Entry"]

AST -->|"references"| Parent Parent -->|"points back to"| AST AST -->|"resolves to"| Type Type -->|"recursively references"| Type Type -->|"defines"| Symbol Symbol -->|"links back to"| AST end ```

The team actually attempted to make Rust work, but quickly realized it was unfeasible without redesigning the entire internal memory model. Redesigning would have meant abandoning a port and spending vast engineering effort solving an entirely new category of architectural problems. Furthermore, Rust offered no tangible advantages over Go in compiled code quality or concurrency throughput for this specific workload. Anders notes with a laugh that Go delivered all the performance and concurrency benefits ("all the bennies") with significantly less friction. While Rust developers can resort to reference counting or custom memory allocators, those approaches require restrictive ergonomics and escape hatches into `unsafe` code blocks, whereas Go's garbage collector operates as a safe, built-in concern.

---

[14:49](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=889s) The Migration Strategy: Syntactic Translation Over Raw LLM Generation

Addressing whether large language models were leveraged for the migration, Anders notes that the native compiler project began two years prior, when LLMs were far less capable than they are today. The team began the migration with manual proofs of concept, authoring the scanner and the parser by hand. Once those prototypes proved that a 10x performance gain was realistically achievable, they confronted the daunting task of migrating the rest of the codebase, which spans between 500,000 and 1,000,000 lines of code.

```mermaid flowchart LR accTitle: TypeScript to Go Migration Pipeline accDescr: Pipeline showing manual prototypes, deterministic transpilation, manual refactoring, and localized AI assistance.

subgraph Step1["1. Validation"] Manual["Manual Scanner & Parser Prototype"] end

subgraph Step2["2. Transpilation"] TSCode["500k-1M Lines of TypeScript"] Transpiler["Deterministic Syntactic Transpiler"] RawGo["Valid Syntax Go Code (Non-compiling)"] TSCode --> Transpiler --> RawGo end

subgraph Step3["3. Stabilization"] Refactor["Refactor Types & Data Structures"] LocalAI["Localized AI Assists & Testing"] RawGo --> Refactor Refactor <--> LocalAI end

Manual --> TSCode ```

Rather than letting an LLM attempt an end-to-end rewrite, the team engineered a deterministic compiler tool that syntactically transformed TypeScript source code into syntactically valid Go. The resulting Go files contained zero syntax errors, though they could not compile immediately because TypeScript's structural type conventions do not map directly to Go's type system. The engineering team then manually refactored the data structures, using AI in a localized, targeted fashion to assist with discrete code transformations and test writing. Anders cautions that turning an LLM loose on hundreds of thousands of lines of code without 100% test coverage is dangerous, as human engineers would still have to audit every generated line to verify that hallucinations had not introduced subtle bugs.

- Migration pipeline details: - Scanner and parser prototypes were hand-written to validate 10x performance potential. - A custom transpiler converted TypeScript syntax directly into Go syntax. - Emitted Go code was syntactically correct but required deep structural type refactoring. - AI was applied surgically for local unit transformations rather than bulk translations.

---

[17:11](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1031s) "Park the Stochasticness": Why AI Should Write Programs, Not Output Answers

Anders highlights a crucial conceptual guideline for applying AI in engineering: developers should use LLMs to create deterministic programs rather than relying on the LLM's raw, probabilistic outputs. Because LLMs are inherently stochastic, there is no guarantee they will generate identical answers across runs. By instructing the model to generate a programmatic translator instead, engineers "park the stochasticness in that program," ensuring that every subsequent execution against the codebase remains entirely deterministic and reproducible.

To illustrate this principle, Anders shares an anecdote about a group vacation with friends. The group needed to balance lodging and travel expenses, so they fed the receipts and payment details into an AI to calculate who owed what:

> "It very authoritatively came up with the wrong answer... because it just forgot like about some of the settlements. But if we had asked it to write a spreadsheet, which is really—that's just a program, right? Then we would have gotten the right answer because it's very good at writing programs."

Validating a small program or spreadsheet formula presents a tiny surface area for human verification compared to validating arbitrary numerical or linguistic claims. While the TypeScript team did not build the native port exclusively through AI, they actively integrate AI tools like GitHub Copilot into everyday maintenance, assigning incoming bug reports and pull request test generation to Copilot first to see if it can produce an automated solution.

---

[19:17](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1157s) Why Full Rewrites Are "Toxic" for Developer Ecosystems

When asked whether the team missed out on optimizations by choosing a direct port over an unconstrained rewrite, Anders rejects the premise: "To be honest, I don't think there are any... we're quite happy with the way this codebase works." In his experience, clean-slate rewrites are often "toxic often for ecosystems" because they inevitably destroy backwards compatibility.

Engineers embarking on greenfield rewrites inevitably decide to fix minor aesthetic grievances or reorganize subsystems under the guise of making things "better or prettier." Every arbitrary alteration cascades into behavioral drift, leaving thousands of existing consumers and downstream tooling to suffer through migration breakage. For a project at TypeScript's scale, strict fidelity to existing behavior is the single most valuable property for user trust, making a mechanical port far superior to a greenfield reimagining.

---

[20:12](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1212s) In Defense of JavaScript: The Genius of Brendan Eich's First-Class Functions

Transitioning to JavaScript's broader reputation, Ryan notes that developers routinely criticize the language's bizarre edge cases and semantic quirks, asking Anders why JavaScript managed to conquer the software industry despite those complaints. Anders immediately pushes back on the premise that JavaScript is fundamentally broken, stating that it is nowhere near as flawed as popular critiques suggest.

Considering that Brendan Eich had only about three to four weeks to design and implement Mocha (the prototype for JavaScript) at Netscape in 1995, he got the most important high-level architectural decisions completely right. Eich's background in functional programming led him to incorporate first-class functions and lexical scoping into the core runtime. Giving developers the ability to nest functions, close over surrounding lexical scope, and pass functions around as first-class values provided the language with an expressive foundation that proved durable enough to support the modern web.

[21:15](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1275s) JavaScript Quirks, TypeScript’s True Role, and the Failure of Replacements

Anders points out that JavaScript is notoriously full of edge cases and bizarre behaviors that drive developers crazy, particularly silent automatic type coercions and the confusing differences between `==` and `===`. However, this is precisely the kind of problem that static type checkers excel at solving: compilers can patiently ferret out these semantic subtleties because they keep all the deep rules of the language in memory, whereas no human developer can realistically track them all in their head. This capability explains a major part of TypeScript's explosive growth: it acts as a filter that brings out the best parts of JavaScript while cleanly walling off the bad parts.

Crucially, JavaScript remains the true universal runtime. While languages like Java were originally marketed as the definitive "write once, run anywhere" cross-platform solution, Java never actually achieved complete reach because it failed to run natively in modern web browsers; JavaScript, on the other hand, genuinely runs everywhere. Ryan brings up prior attempts to supplant or improve the language, such as CoffeeScript and Dart, asking why they failed to dominate. Anders explains that CoffeeScript was merely alternative syntactic sugar for JavaScript that altered neither its core semantics nor provided meaningful tooling. Dart, meanwhile, attempted to replace JavaScript outright. Anders argues that attempting to replace an entire language works against the developer ecosystem; instead, the winning strategy was TypeScript’s philosophy of meeting the community where it lived: "We weren't trying to change JavaScript; we were trying to improve JavaScript."

[23:28](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1408s) How AI Cemented Incumbent Languages and Made TypeScript #1

Addressing the hypothesis that AI might make it easy to migrate away from flawed legacy languages toward cleaner modern alternatives, Anders argues the opposite is taking place. Large language models reflect their training distributions: they are strongest at the languages they have seen the most code for in open-source repositories. An AI trained on the internet is remarkably fluent in JavaScript, TypeScript, and Python, but completely clueless about a newly invented, niche language. To use a novel language with an LLM, a developer would have to waste massive context-window tokens just explaining the syntax and grammar before even posing the prompt. Consequently, AI acts as a moat that entrenches incumbent languages.

Anders observes a distinct upward knee in the curve of TypeScript adoption that lines up directly with the rise of modern AI. Over the past year, TypeScript passed JavaScript to become the single most used language on GitHub, now accounting for more than 50% of the combined JavaScript/TypeScript footprint on the platform and surpassing Python as well. Anders notes that virtually no developer prompts AI to write raw JavaScript today because LLMs perform significantly better when generating TypeScript: the static type annotations keep the model on track, reducing hallucinated bugs. Furthermore, TypeScript enables static validation loops: while raw JavaScript can only be validated by spinning up a full runtime environment (which sandboxed LLMs often cannot easily do), a model can simply pass TypeScript through the compiler, get back precise error messages, and silently patch its mistakes before the human developer ever sees the output.

```mermaid flowchart TD accTitle: AI Self-Correction Workflow with TypeScript accDescr: Diagram illustrating how LLMs use TypeScript static analysis to self-correct code without needing a live runtime.

subgraph LLM_Sandbox["LLM Sandboxed Environment"] A["LLM Generates Code"] --> B["Emit TypeScript Code"] B --> C["Run Static Type Checker / Compiler"] C --> D{"Type Errors Found?"} D -- "Yes" --> E["Feed Diagnostic Errors Back into LLM Context"] E --> A D -- "No" --> F["Present Clean, Working Code to User"] end ```

[26:32](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1592s) Why JavaScript on the Backend Makes Sense: Orchestration vs. Inner Loops

Ryan questions why anyone would still choose to run JavaScript or TypeScript on the backend given that native languages run up to 10x faster. Anders emphasizes that raw computation speed is rarely the actual bottleneck of a system. Developer productivity often relies on ecosystem maturity: JavaScript and TypeScript have world-class web server frameworks that get products to market far faster than starting from scratch in a native language that was never designed for web environments.

Anders compares modern web servers to machine learning pipelines written in Python. Nobody argues that Python is inherently high-performance; rather, all the timer-critical model training routines are written in native code, and Python serves simply as the high-level orchestration language. Web servers act in much the same way: TypeScript is usually orchestrating database queries, I/O calls, and network requests. Whether an inner loop is running compiled native code matters very little when the app is I/O-bound—and V8’s Just-In-Time (JIT) compiler compiles hot loops to machine code anyway. He summarizes his rule of thumb: always profile first before making architecture bets, because real-world performance measurements almost always surprise engineers.

[28:26](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1706s) The Compounding Slowdown: Codebase Scale and Compiler Sophistication

Reflecting on why rewriting the TypeScript compiler in Go was not undertaken sooner, Anders admits that the team never anticipated the sheer magnitude of the codebases developers would eventually build. When the TypeScript project began in 2012, no one imagined massive codebases running on it; today, applications like Visual Studio Code contain roughly 2.3 million lines of code, and internal Microsoft repositories exceed 10 million lines.

At the same time, the compiler itself grew vastly more demanding. Over the years, the team introduced rich, expressive features such as union types, discriminated unions, and complex control flow analysis. While these features elevated the precision of type checking, each new feature carried an incremental computational cost: Anders reveals that TypeScript 6 runs at roughly 50% of the raw throughput speed of TypeScript 1.5, even though it accomplishes dramatically more work. When combined with the end of CPU clock-speed scaling under Moore’s Law and JavaScript’s inherent inability to scale type checking across multiple cores, this explosion in codebase size and compiler analysis caused the compile-time bottlenecks that eventually made the native Go rewrite essential.

- **Scale of modern TypeScript codebases**: Visual Studio Code is around 2.3 million lines of code, with some internal enterprise repositories surpassing 10 million lines. - **Compiler throughput over time**: TypeScript 6 runs at approximately half the processing speed of TypeScript 1.5 due to advanced features like control-flow analysis and discriminated unions. - **Ecosystem context**: The early competition between TypeScript and Facebook’s Flow type checker is touched upon, with TypeScript ultimately pulling ahead in large part because its self-hosted architecture fostered broad adoption.

[03:19:57](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=11997s) Tooling-First Compilers: TypeScript vs. Flow

Anders Hejlsberg reflects on the early architectural choices that allowed TypeScript to thrive while competing projects struggled. A major advantage TypeScript had over Facebook's Flow was that writing the TypeScript compiler in JavaScript made it vastly easier for the community to contribute. Flow was implemented in OCaml, meaning anyone who wanted to contribute had to learn an entirely different programming language and functional mindset.

```mermaid flowchart TD accTitle: TypeScript Architecture vs Traditional Compilers accDescr: Contrasts traditional machine code generation with TypeScript's language service and editor tooling architecture.

subgraph Traditional["Traditional Compiler Focus"] T1["Source Code"] --> T2["Parser & Lexer"] T2 --> T3["Type Checker"] T3 --> T4["Machine Code Generation"] end

subgraph TypeScriptApproach["TypeScript Tooling-First Approach"] TS1["TypeScript Source"] --> TS2["Compiler Core"] TS2 --> TS3["Language Service"] TS3 --> IDE1["Visual Studio / VS Code"] TS3 --> IDE2["Third-Party Editors"] IDE1 -.-> Feat["Statement Completion<br/>Red Squigglies<br/>Interactive Editing"] IDE2 -.-> Feat end ```

Beyond language choice, Flow neglected IDE-based tooling, whereas the TypeScript team understood from day one that their goal was never to generate machine code; it was to create superior developer tooling. Alongside the compiler, they engineered a language service deeply integrated into Visual Studio and Visual Studio Code—and exposed to external editors via open protocols. A standalone type checker is helpful, but developers fundamentally need an interactive experience: statement completion, live red squigglies, and real-time feedback as they type.

[03:32:59](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=12779s) What It Takes to Build a Programming Language

Hejlsberg jokes that "the world needs another programming language like it needs another hole in the head." Embarking on language design requires a specific disposition because, while compilers are a fascinating field dating back to the dawn of computer science, building one demands mastering two entirely distinct disciplines:

1. **The Mechanics:** Implementing scanners, lexers, parsers, type checkers, and code generators. 2. **The Art of Design:** Crafting the ergonomics, aesthetics, and user experience to make the language feel coherent and natural.

A harsh reality of language development is that every new language is roughly 10% novel concepts and 90% the same mundane drudgery required by every other language. Creators must accept mountains of unglamorous groundwork. Furthermore, designers stand on the shoulders of giants; creating a great language requires deeply studying existing paradigms—procedural, object-oriented, and functional programming.

Above all, language development is an exceptionally long game. Every language Hejlsberg has created required at least a decade of dedicated commitment, and "it's really never until version three that it truly starts to get okay." Anyone who loses interest quickly and moves on to new problems is simply not cut out for language design, which is why veteran designers tend to stay in the field for decades.

[03:35:37](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=12937s) The Influence of Functional Programming

Asked which paradigms or languages he admires outside his own creations, Hejlsberg highlights functional programming. He views functional programming as educational because it approaches software fundamentally closer to mathematics than to machine execution.

These concepts heavily influenced the TypeScript compiler itself. Substantial parts of the compiler are written in a pure functional style, relying on immutable data structures. Because the structures are immutable, they can be safely shared across threads or processes using shared memory concurrency without data mutation issues. He admits that weaving "islands of pure functional programming inside an imperative program" alongside concurrency is technically demanding, but it delivers massive benefits. Rather than worshiping any single language, he emphasizes that every language teaches valuable lessons.

[03:37:07](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=13027s) Will Programming Languages Disappear? The Bar for Ecosystems

When asked whether the number of programming languages will shrink over the next decade, Hejlsberg notes that AI heavily favors incumbents. Even before the emergence of AI, the barrier to entry for establishing a viable programming language had risen dramatically:

- **Past requirements:** A basic compiler. - **Modern requirements:** A rich language service, full IDE integrations, debuggers, profilers, extensive libraries and frameworks, and cross-platform code generators.

Responding to the speculative idea that LLMs might someday bypass high-level source code to generate machine code directly, Hejlsberg is skeptical:

| Representation | Information Density | AI Suitability | |:--- |:--- |:--- | | **High-level Source Code** | High condensed meaning, minimal noise; variable names reflect user intent | Well-suited: directly emulates human thought and semantic intent | | **Machine Code** | Extremely noisy; ~50% of instructions are arbitrary memory addresses or register assignments | Poorly suited: hard to extract signal from noise; detached from user prompts |

Hejlsberg points out that neural networks are essentially emulators of human cognition. Humans invented high-level programming languages precisely because human brains cannot manage raw machine code; AI faces the exact same semantic challenges when trying to reason about logic.

[03:39:56](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=13196s) Evolution from Solo Hacker to Team Leader, and the Number One Language Design Trap

Reflecting on his journey from Turbo Pascal through C# and TypeScript, Hejlsberg discusses how scale forced him to change. Turbo Pascal began during the era of 8-bit microprocessors with 64 KB of memory, where a single person could control every byte and operate as a complete "one-man shop." But as memory expanded to 640 KB and then exploded into modern multi-gigabyte architectures, solo development became impossible. For a perfectionist, learning to let go, delegate, and become a collaborative team player was a vital and challenging personal evolution.

When asked about the most common failure mode among aspiring language designers, Hejlsberg identifies an imbalance of priorities: - **Over-indexing on a pet feature:** Creators focus obsessively on one novel syntax trick or paradigm ("Wouldn't it be cool if my language could do X?"). - **Under-indexing on the basics:** They neglect standard libraries, error reporting, interoperability, and tooling.

The result is a language that executes one narrow feature well, while everything else feels broken or clunky, leaving developers with a net-negative experience.

He concludes by reiterating that programming languages never evolve in isolation. During his work on C#, the team continually tracked other languages, adopting powerful ideas from functional programming, while other ecosystems simultaneously borrowed innovations from C#.

[42:40](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=2560s) Cross-Pollination Across Languages and the Tension of Letting Go

Anders reflects on how ideas naturally circulate throughout programming language history. Features pioneered in C#, such as `async`/`await`, were eventually adopted by JavaScript and numerous other ecosystems. The industry advances collectively because language creators continually learn from one another's successes.

```mermaid flowchart LR accTitle: Feature Migration Across Modern Languages accDescr: Diagram showing C# pioneering async patterns which subsequently spread to JavaScript and other modern languages. subgraph Pioneer["Pioneering Work"] CS["C# (async/await)"] end subgraph Adoption["Ecosystem Adoption"] JS["JavaScript (ES2017)"] Others["Other Modern Languages"] end CS --> JS CS --> Others ```

Ryan pivots to the career dilemma many senior engineers face: transitioning from hands-on individual contributor work to delegating and "letting go." When asked how he learned that skill, Anders offers what he terms a "counter story." During the C# days, his primary responsibility was serving as the lead language designer—authoring specifications and designing features—rather than implementing the C# compiler itself. Having done intense, active coding earlier in his career on Turbo Pascal, he realized he had backed away from implementation too far.

- C# pioneered mainstream `async`/`await` primitives before they became ubiquitous across JavaScript and other language communities. - Anders moved away from hands-on implementation during the C# compiler's early days, focusing instead on language design specifications.

[43:52](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=2632s) Avoiding the "Architecture Astronaut" Trap

By stepping away from compiler internals, Anders found himself drifting up into the stratosphere, turning into an "architecture astronaut." While he was still writing some code within the runtime frameworks and core libraries, it lacked the deep, intellectually punishing challenges found in core systems implementation. Slowly, without fully realizing it, his day-to-day satisfaction degraded:

> "I wasn't getting my hands dirty. I was writing stuff in the framework and in the libraries, but... these are not like the deep, really super hard problems to solve, right? And I didn't really know it at the time, but I was gradually getting less happy with the work that I was doing... I finally realized I'm just a happy coder, you know? I mean, I like the spec stuff too, but coding is like, man, that's what gets me up in the morning, make coffee, and write some code."

When TypeScript started, Anders seized the opportunity to roll up his sleeves and actively co-author the compiler code. When Ryan asks how an engineer operating at Microsoft Technical Fellow rank justifies writing raw code given organizational impact expectations, Anders explains that high-level impact and active coding reinforce each other. By maintaining ownership over a specific corner of the codebase, he catches emergent friction during pull requests and spots architectural decay firsthand. An architect disconnected from implementation can talk about syntax, but loses the ability to speak credibly about the practical tool developers confront every day.

- Anders turned down multiple opportunities to transition into engineering management, consciously choosing to remain an individual contributor because management was not where he did his best work. - Staying in the trenches allows senior leads to catch subtle code smells, identify refactoring opportunities early, and understand practical runtime constraints rather than merely theorizing about grammar.

[47:10](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=2830s) The Origins of TypeScript: Script# and Fixing JavaScript

Anders recounts how TypeScript was born from an unexpected enterprise demand originating within the Outlook.com engineering team. The Outlook group approached the C# team asking Microsoft to productize **Script#**—an internal project that compiled C# directly into JavaScript so client applications could run in the browser.

Anders was initially baffled by the request:

> "I'm like, what? Why? Why would you want to do that? Why don't you just write JavaScript? 'Well, because that way we can get great tooling. Then we can use Visual Studio, and we can have projects, and we can have type checking, and we can have code refactoring and navigation, and we can write interfaces and people can understand how this all works.' And I'm like, 'Wow, is JavaScript really that busted?' And you're saying like the way you want to fix that problem is by abandoning JavaScript, treating it as an instruction language, right? And then having a code generator target it. I'm like, couldn't we like fix JavaScript? Wouldn't that be better?"

Rather than treating JavaScript as a compiler target like bytecode or assembly, Anders believed the industry needed to meet developers where they already were: by preserving JavaScript's semantics while layering ergonomic type checking and language services on top. That realization catalyzed the creation of TypeScript.

[49:14](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=2954s) Why AI Agents Demand Ultra-Fast Tooling

Ryan asks about Anders's claim in recent talks that tooling performance matters far more in the age of AI. Anders explains that development workflows are shifting from single human editors to swarms of background autonomous agents. While AI agents generate massive volumes of code and make human-like mistakes, the primary bottleneck becomes feedback latency.

```mermaid flowchart TD accTitle: Agentic Code Modification and Semantic Validation Cycle accDescr: Autonomous agent loop showing code generation, semantic validation via compiler LSP, and fast feedback iterations. subgraph AgentLoop["Agent Execution Loop"] Agent["Autonomous AI Agent"] -->|"Modifies Code"| Edit["Code Changes"] Edit -->|"Invokes Compiler / LSP"| Checker["Fast Semantic Type Checker"] Checker -->|"Instant Error / Symbol Info"| Feedback["Feedback Loop"] Feedback -->|"Iterates"| Agent end subgraph ProblemArea["Naive Fallback"] Grep["Naive Text Grep (Breaks on shared symbol names)"] end Agent -.->|"Fails on ambiguous symbols"| Grep ```

Large language models already suffer from generation latency. If an LLM must wait two minutes for a compiler to type-check every speculative edit in a monorepo, the agentic loop grinds to a halt. Furthermore, agents cannot reliably rely on text-based tools like `grep` when refactoring ubiquitous property names (such as a generic `version` field shared by dozens of unrelated data structures). To avoid widespread breakages, agents must perform true semantic search and refactoring through the compiler's Language Server Protocol (LSP) or command-line compiler interfaces. Because compilers are running silently in the background on behalf of multiple agents, sub-second tooling execution is indispensable.

- Compilers are invoked far more frequently by automated agents than by human typists, multiplying the cumulative cost of slow type-checking. - Refactoring identical property names across vast codebases requires compiler-driven AST and semantic analysis rather than textual find-and-replace.

[51:16](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3076s) Evaluating the Hype: Can AI Write 90% of Code?

Ryan introduces popular predictions circulating online, starting with the claim that AI will write over 90% of all code within a year. Anders offers a measured distinction between raw volume and intellectual novelty. In sheer lines of code, AI writing 90% may already be a self-fulfilling prophecy because agents generate massive boilerplate and scaffolding at superhuman speed.

However, Anders firmly pushes back on the idea that AI will write 90% of *high-quality, novel* software:

- For boilerplate applications and AI-generated scaffolding, models can already write 100% of the code. - When it comes to novel algorithms that have never been written before, or complex system architectures, current LLMs are incapable of independent end-to-end design. - Anders points directly to their internal experiments with the TypeScript compiler: the team attempted to have AI build or rewrite core parts of the compiler, and the models simply could not do it.

[53:00](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3180s) The Stochastic Nature of AI and the Illusion of 100% Replacement

Anders explains why current generative models struggle so much when tasked with generating or migrating complex systems like the TypeScript compiler. A compiler is far from typical application code: it relies on novel internal architectures and niche design concepts that simply do not exist in the training corpus. At its core, an LLM is a massive stochastic engine that has memorized the public internet and possesses a modest ability to extrapolate beyond that data. When an architecture falls completely outside what it has ingested, it predictably fails. While its capabilities are wildly impressive and constantly improving, Anders believes there remains a massive gulf between assisting developers and doing everything end to end—adding with a chuckle that he hopes it never reaches that point, because otherwise "what's the point of humans anymore?"

Ryan brings up the popular prediction that within a year engineers will no longer need IDEs or even have to read code. Anders counters that handing the keys over entirely to AI is a recipe for disaster. The moment an LLM fails to implement a feature or cannot resolve a subtle bug, an engineer who does not understand the underlying system is completely powerless. Furthermore, software development carries real-world accountability: if an application ends up draining a user's bank account, the company gets sued, not the AI model. Someone has to take responsibility for what the system does, and Anders stresses that he personally would not be able to sleep at night vouching for production code he could not comprehend.

Addressing why his grounded perspective diverges so sharply from the hyper-optimistic claims emerging from labs like Anthropic, Anders points out that people love extrapolating progress "all the way to 100%." While AI can reach increasingly higher percentages of code output, human developers are still essential to connect technical implementation with business objectives, organizational architecture, and real-world domain requirements. Treating AI as an independent entity that makes humans entirely obsolete fundamentally misunderstands the reality of software engineering.

---

[56:04](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3364s) Junior Engineers, Code Review, and the Changing Craft

Turning to the question of whether AI will replace junior software engineers within three years, Anders highlights an obvious contradiction: if companies eliminate junior developers, where will their future senior engineers come from? Engineering organizations cannot survive down the road without experienced senior leadership, and those seniors must be trained through early-career practice.

What is happening instead is a structural narrowing at the base of the engineering pyramid. Companies expect engineers to level up faster so they can step into supervisory roles. The core craft of software engineering is pivoting away from manually typing lines of syntax and toward directing AI agents and reviewing their output:

```mermaid flowchart LR accTitle: Evolution of the Software Engineering Role accDescr: Diagram illustrating the shift from manual code writing to managing and reviewing AI agents. subgraph Traditional["Traditional Engineering"] A["Write Syntax Manually"] --> B["Build & Run Tests"] end subgraph Modern["AI-Assisted Workflow"] C["Direct AI Agents"] --> D["Review Agent Diffs"] D --> E["Validate System Behavior"] end ```

Anders acknowledges that while many developers thrive in this high-level orchestrator workflow, it represents a deep transformation of the job. Having spent four to five decades loving the tactile act of writing code, he still intends to write critical core systems himself. However, he is more than happy to offload the repetitive drudgery, such as boilerplate testing logic and navigating rigid test frameworks. He admits that code review has always felt harder and less enjoyable than writing code from scratch. Current tooling remains poor—often reducing review to a raw list of file diffs—and he envisions AI being used more effectively to summarize, explain, and contextualize changes to make code review far more ergonomic.

---

[58:52](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3532s) Technical Milestones: Multithreading in Go vs. Z80 Assembly in Turbo Pascal

Reflecting on the hardest technical challenges across his career, Anders highlights two vastly different eras: modern shared-memory concurrency and extreme resource scarcity in the early PC era.

In the native rewrite of the TypeScript compiler, porting the code to a native language was relatively straightforward. The true beast was concurrency: forcing a compiler—traditionally written as a purely sequential pipeline—to fully saturate every CPU core on a developer's machine. Achieving this meant coordinating massive shared data structures across worker threads without introducing race conditions, accidental data mutations, or deadlocks.

```mermaid flowchart TD accTitle: Modern Concurrency vs Vintage Resource Constraints accDescr: Comparison of the concurrency challenges in TypeScript Native versus memory squeezing in Turbo Pascal. subgraph TS["TypeScript Native (Go)"] TS1["Sequential AST Pipeline"] --> TS2["Shared-Memory Concurrency"] TS2 --> TS3["Saturate All Available CPU Cores"] TS2 --> TS4["Eliminate Race Conditions & Deadlocks"] end subgraph Turbo["Turbo Pascal (Z80 Assembly)"] TP1["Write Compiler, Editor & Runtime in Assembly"] TP1 --> TP2["Strict 12 KB EPROM Ceiling"] TP2 --> TP3["Replace Long Jumps with Short Jumps to Save Single Bytes"] end ```

Contrasting this with his early career, Anders recalls starting out on 8-bit microcomputers running Microsoft BASIC in ROM, typing in text-only Star Wars games where scrolling text warned of Klingons in sector K4. Driven to discover what made the hardware tick, he learned assembly and built the first version of Turbo Pascal entirely in Z80 machine code—including the compiler, interactive editor, and runtime library. Hardware limitations were unforgiving:

- **12 KB EPROM Budget:** Code had to fit into tightly constrained ROM chips, turning optimization into a byte-by-byte puzzle. - **Micro-optimizations:** Squeezing twenty bytes out of an over-budget binary meant hunting for opportunities to swap a long jump instruction for an intermediate short jump just to save a single byte. - **Craftsmanship:** Anders describes early assembly development as feeling closer to woodworking than modern software development, contrasting that obsessive micro-crafting with today's world of "bottomless pits of capacity and bottomless pits of expectation."

---

[01:02:05](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3725s) Top Book Recommendation: Algorithms + Data Structures = Programs

When asked for his definitive book recommendation for software engineers, Anders points to *Algorithms + Data Structures = Programs* by Niklaus Wirth (the designer of Pascal, Modula-2, and Oberon). Anders values the book because it keeps heavy mathematical formalism and symbolism to a minimum, prioritizing clear explanations and practical, instructive code examples.

As a largely self-taught developer, Anders originally knew only linked lists, which he had used for all the symbol tables in early versions of Turbo Pascal. As programs defined more local variables, search times grew exponentially. Reading Wirth's chapter on hash tables was an eye-opening revelation: discovering that simple hashing could provide near-constant lookup times prompted him to immediately rewrite Turbo Pascal's symbol lookup. The compiler ran twice as fast overnight, leaving him thinking, "Holy cow."

[01:03:22](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3802s) Practical Compiler Design and Error Recovery

Reflecting further on his favorite foundational literature—specifically Niklaus Wirth's classic work—Anders emphasizes how immensely practical it was from an engineering perspective. Rather than remaining purely academic or theoretical, the text demystified concrete problems like implementing syntax error recovery and walking readers through how to actually construct a simple, functioning compiler step by step. While the book has been out of print for thirty or forty years, Anders notes that today it is readily accessible as a downloadable PDF floating around online for anyone eager to understand compiler fundamentals from the ground up.

[01:03:50](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3830s) Advice to a Younger Self: Collaboration and Ignoring the "Impossible"

Turning toward a career retrospective, Ryan asks Anders what piece of guidance he would deliver to his younger self just entering the tech industry with the benefit of decades of experience behind him. Anders offers two distinct insights. First, echoing an earlier point about career growth, he notes that he would have told himself to learn how to be a better team player much earlier in his career rather than having to learn that lesson later on.

Second, Anders stresses the importance of not being deterred by skeptics: "Don't let people tell you that it can't be done. When they tell you it can't be done, it's because *they* can't do it. That doesn't mean that you couldn't possibly do it." When Ryan asks if there was a specific project where someone told him something was impossible before he went ahead and did it, Anders points straight to the genesis of his career: Turbo Pascal. When he and his collaborators first demonstrated what they had built—an astonishingly fast, integrated development environment running in memory on microcomputers—observers scoffed in disbelief:

> "Whenever we told them here's what we have, they said that can't be done. That's like, 'Nah, you guys are full of... that's like not possible,' you know. Well, it was. And I didn't know that it wasn't possible, right?"

[01:05:00](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3900s) Outro: Community Recommendations and the Ergonomic Keyboard Project

Closing out the interview, Ryan thanks Anders for his time and insights, and Anders expresses how much fun he had during the discussion.

Turning to his audience, Ryan asks viewers to support the channel with likes and comments if they want to help the show grow, encouraging them to leave suggestions for future interviewees. He highlights that previous high-profile guests—including Turing Award winners and distributed systems pioneers like Barbara Liskov, Michael Stonebraker, and Marc Brooker—were originally booked because audience members suggested them in the comments section.

Finally, Ryan shares an update on his personal venture outside of the podcast: designing and manufacturing a custom ergonomic split keyboard that he felt was missing from the market. Holding up a prototype inside its carrying case, he shares that the project recently launched on Kickstarter and managed to hit its total funding goal within just eight hours. As the team transitions into the extensive, multi-month process of industrial tooling, Ryan notes that late pledges have been left open on the campaign page for interested viewers.

## Notable quotes > [00:00](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=0s) People love these like take it all the way to 100%, right? And that's where I get off the bus. — Anders Hejlsberg

> [07:29](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=449s) Moore's Law has stopped giving us faster CPUs. It's giving us more CPUs, and we got to like find ways to use them in our compute-intensive workloads or else we're leaving money on the table. — Anders Hejlsberg

> [17:11](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1031s) It very authoritatively came up with the wrong answer... because it just forgot like about some of the settlements. But if we had asked it to write a spreadsheet, which is really—that's just a program, right? Then we would have gotten the right answer because it's very good at writing programs. — Anders Hejlsberg

> [21:15](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1275s) We weren't trying to change JavaScript; we were trying to improve JavaScript. — Anders Hejlsberg

> [32:59](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1979s) the world needs another programming language like it needs another hole in the head. — Anders Hejlsberg

> [32:59](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=1979s) it's really never until version three that it truly starts to get okay. — Anders Hejlsberg

> [43:52](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=2632s) I wasn't getting my hands dirty. I was writing stuff in the framework and in the libraries, but... these are not like the deep, really super hard problems to solve, right? And I didn't really know it at the time, but I was gradually getting less happy with the work that I was doing... I finally realized I'm just a happy coder, you know? I mean, I like the spec stuff too, but coding is like, man, that's what gets me up in the morning, make coffee, and write some code. — Anders Hejlsberg

> [47:10](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=2830s) I'm like, what? Why? Why would you want to do that? Why don't you just write JavaScript? 'Well, because that way we can get great tooling. Then we can use Visual Studio, and we can have projects, and we can have type checking, and we can have code refactoring and navigation, and we can write interfaces and people can understand how this all works.' And I'm like, 'Wow, is JavaScript really that busted?' And you're saying like the way you want to fix that problem is by abandoning JavaScript, treating it as an instruction language, right? And then having a code generator target it. I'm like, couldn't we like fix JavaScript? Wouldn't that be better? — Anders Hejlsberg

> [01:03:50](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3830s) Don't let people tell you that it can't be done. When they tell you it can't be done, it's because they can't do it. That doesn't mean that you couldn't possibly do it. — Anders Hejlsberg

> [01:03:50](https://www.youtube.com/watch?v=cywK3XYYJ2o&t=3830s) Whenever we told them here's what we have, they said that can't be done. That's like, 'Nah, you guys are full of... that's like not possible,' you know. Well, it was. And I didn't know that it wasn't possible, right? — Anders Hejlsberg

## Mentioned Anders Hejlsberg, Ryan Peterman, TypeScript, C#, Go, Rust, Zig, JavaScript, Python, Java, Dart, CoffeeScript, OCaml, Strata, Internet Explorer, Google V8, Clang, GCC, WebAssembly, esbuild, SWC, GitHub Copilot, Flow, Brendan Eich, Netscape, Mocha, Anthropic, Microsoft, Visual Studio, Visual Studio Code, GitHub, Turbo Pascal, Outlook.com, Script#, Niklaus Wirth, Algorithms + Data Structures = Programs, Pascal, Modula-2, Oberon, Barbara Liskov, Michael Stonebraker, Marc Brooker, Z80, Kickstarter

## Video description Anders Hejlsberg is the creator of TypeScript and C#, and I asked him about how the TypeScript compiler got 10x faster through a rewrite in Go and his thoughts on how AI has impacted software engineering.

• My ergonomic keyboard project I mentioned, you can follow along here: https://read.compose.llc/ • The Kickstarter page for it: https://www.kickstarter.com/projects/ryanlpeterman/compose-simple-ergonomics-beautifully-done

𝗣𝗼𝗱𝗰𝗮𝘀𝘁 𝗹𝗶𝗻𝗸𝘀:

• Spotify: https://open.spotify.com/episode/1thvWd3ClYQHvaUX9qKckk?si=pmojE4jTSPmHVnm4fydbFg • Apple: https://podcasts.apple.com/us/podcast/the-peterman-pod/id1777363835 • Transcript: https://www.developing.dev/p/creator-of-typescript-10x-faster

𝗧𝗵𝗮𝗻𝗸 𝘆𝗼𝘂 𝘁𝗼 𝘁𝗵𝗶𝘀 𝗲𝗽𝗶𝘀𝗼𝗱𝗲'𝘀 𝘀𝗽𝗼𝗻𝘀𝗼𝗿𝘀 𝗳𝗼𝗿 𝘀𝘂𝗽𝗽𝗼𝗿𝘁𝗶𝗻𝗴 𝗺𝘆 𝘄𝗼𝗿𝗸:

• WorkOS: makes your app Enterprise Ready with easy to use APIs to add SSO, SCIM, RBAC, and more in just a few lines of code, check them out at https://workos.com/ • Jira by Atlassian: Get more work done with your favorite agents and models all in one place, check them out at https://jira.dev/

𝗧𝗶𝗺𝗲𝘀𝘁𝗮𝗺𝗽𝘀:

00:00 Intro 00:48 Why write a compiler in JavaScript 07:29 Why rewrite the compiler in Go 14:49 LLMs for large migrations 20:12 Why Javascript is so popular 26:32 Why ever use Javascript on the backend 32:59 What it takes to build a programming language 37:06 Will there be fewer languages in 10 years 42:57 Hands on engineering vs delegation 49:14 Why fast tooling matters more now 51:16 AI software engineering predictions 58:52 The most technically challenging work 01:02:04 Top book recommendation 01:03:50 Advice for his younger self 01:05:00 Outro

𝗪𝗵𝗲𝗿𝗲 𝘁𝗼 𝗳𝗶𝗻𝗱 𝗔𝗻𝗱𝗲𝗿𝘀:

• GitHub: https://github.com/ahejlsberg • X/Twitter: https://x.com/ahejlsberg • Wikipedia: https://en.wikipedia.org/wiki/Anders_Hejlsberg • LinkedIn: https://www.linkedin.com/in/ahejlsberg/

𝗪𝗵𝗲𝗿𝗲 𝘁𝗼 𝗳𝗶𝗻𝗱 𝗥𝘆𝗮𝗻:

• Newsletter: https://www.developing.dev/ • X/Twitter: https://x.com/ryanlpeterman • LinkedIn: https://www.linkedin.com/in/ryanlpeterman/ • Threads: https://www.threads.com/@ryanlpeterman • Instagram: https://www.instagram.com/ryanlpeterman • TikTok: https://www.tiktok.com/@ryanlpeterman

𝗥𝗲𝗳𝗲𝗿𝗲𝗻𝗰𝗲𝗱 𝗶𝗻 𝘁𝗵𝗶𝘀 𝗲𝗽𝗶𝘀𝗼𝗱𝗲:

• Flow type checker repository: https://github.com/facebook/flow • TypeScript compiler repository: https://github.com/microsoft/TypeScript • Algorithms + Data Structures = Programs (book): https://en.wikipedia.org/wiki/Algorithms_%2B_Data_Structures_%3D_Programs • TypeScript native rewrite: https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/

[Source](https://www.youtube.com/watch?v=cywK3XYYJ2o)

中文简报

Anders Hejlsberg 使用 Go 重写 TypeScript 编译器 TypeScript 通过使用 Go 重写其编译器实现了十倍的性能提升,因为 JavaScript 的单线程事件循环和内存模型构成了无法避免的执行瓶颈。 Anders Hejlsberg 剖析了将 TypeScript 编译器从 JavaScript 迁移至 Go 背后的工程考量,解释了单线程运行时瓶颈、循环图数据结构以及单核摩尔定律的终结为何使 Go 成为优于 Rust 的理想目标,同时排除了不向后兼容的全新重写方案。他详细介绍了他们采用确定性语法转译器而非原生大语言模型的迁移策略,并告诫不要依赖随机性工具进行大规模重写。Hejlsberg 还评估了 AI 的实际影响,指出尽管智能体会生成大量脚手架代码并需要极快的编译器反馈循环,但人类工程师在系统理解、新颖架构以及现实中的法律和商业问责方面仍然不可或缺。最后,他分享了数十载职业生涯的心得,强调了坚持亲自动手写代码、避免成为脱离实际的“架构宇航员”的价值。 TypeScript 编译器通过使用 Go 进行原生重写实现了 10 倍的性能提升,支持跨多个 CPU 核心的共享内存并发,克服了单线程 JavaScript 的性能极限。 (7:29) 之所以选择 Go 而非 Rust,是因为 TypeScript 编译器严重依赖 AST 节点与符号表之间的循环引用图,如果不彻底重构内部内存模型,自动垃圾回收就成为必不可少的特性。 (12:16) 面对 50 万至 100 万行代码的编译器迁移,团队构建了确定性语法转译器,而非依赖批量大语言模型翻译,从而避免了在庞大代码库中审查幻觉 Bug 所带来的无法承受的负担。 (14:49) 自主编程智能体的兴起使得快速的编译器工具链变得更加关键,因为机器调用语义类型检查和重构工具的频率远高于人类,使延迟成为了主要瓶颈。 (49:14)

Reading summary

Anders Hejlsberg argues that porting the TypeScript compiler to Go unlocks essential multi-core concurrency while preserving ecosystem compatibility, and contends that artificial intelligence will augment software engineering rather than replace human developers. Native Compiler Migration: Choosing Go Over Rust (7:29) The TypeScript compiler was originally self-hosted in JavaScript to establish an immediate feedback loop and run across platforms. However, codebase scale exploded—with projects like Visual Studio Code reaching 2.3 million lines and enterprise repositories exceeding 10 million—while compiler throughput dropped by roughly 50% between versions 1.5 and 6 due to advanced features like control-flow analysis and discriminated unions. Because JavaScript is single-threaded and worker communication requires expensive serialization, the team needed native multi-core execution to exploit modern hardware as single-core clock scaling plateaued. Rather than launching a greenfield rewrite—which Hejlsberg describes as toxic to ecosystems due to behavioral drift and broken compatibility—the team pursued a faithful port. Go was chosen over Rust because the TypeScript codebase fundamentally relies on automatic garbage collection, closures, and heavily cyclic memory structures. AST parent pointers, recursive types, and scope-linked symbol tables conflicted with Rust's borrow checker, whereas Go provided built-in garbage collection and shared-memory concurrency without requiring a complete redesign of the internal memory model. Deterministic Migration and Parking the Stochasticness (14:49) Migrating a codebase spanning 500,000 to 1,000,000 lines of code required strict architectural discipline rather than trusting large language models with bulk translations. After hand-written scanner and parser prototypes demonstrated a potential 10x performance improvement, the team built a deterministic compiler that translated TypeScript syntax directly into syntactically valid Go. Engineers then manually refactored the structural type system, utilizing AI tools only for targeted, local transformations and unit tests. Hejlsberg outlines a core design principle: developers should prompt models to produce deterministic programs rather than relying on raw probabilistic outputs. Because LLMs are stochastic and can authoritatively invent incorrect answers, asking an AI to generate a translation tool or a calculation script "parks the stochasticness" inside a verifiable artifact. This narrows the human review surface to inspectable code rather than auditing massive, non-reproducible outputs. Tooling Feedback Loops and Language Incumbency (23:28) Hejlsberg challenges predictions that AI will allow rapid transitions away from flawed legacy languages, arguing instead that AI acts as a moat for incumbents. Because models reflect open-source training data, they excel at established languages like JavaScript, TypeScript, and Python while struggling with niche alternatives. TypeScript surpassed JavaScript and Python as the primary language on GitHub partly because static type annotations constrain LLMs, reducing hallucinated errors and allowing automated static check-and-repair loops before code is delivered to users. Furthermore, the emergence of autonomous AI agents demands ultra-fast developer tooling. Agents iterate by generating speculative edits and invoking compilers to validate AST semantics and resolve shared property names where simple text searches fail. If compiler diagnostic cycles take minutes instead of sub-seconds, background agent swarms become unusable. Novel Architecture, Liability, and Engineering Roles (53:00) Hejlsberg rejects forecasts that AI will automate 90% of novel software engineering or render IDEs and human comprehension obsolete. Current generative models rely on training distributions and struggle to design novel algorithms or specialized architectures, such as compilers. Additionally, organizational accountability demands human oversight: when applications cause financial or operational damage, legal liability rests on the engineering organization, not the model. Addressing the career ladder, Hejlsberg warns that eliminating junior developers would destroy the talent pipeline required to produce future senior leaders. While the craft is shifting away from typing raw syntax toward directing agents and reviewing file diffs, human engineers remain essential for connecting technical implementation to domain constraints, business architecture, and final system accountability. While Hejlsberg embraces automated assistance for repetitive tasks like test generation, he maintains that deep systems engineering requires human architectural design. The continuing transition toward agentic workflows makes sub-second compiler performance vital, leaving the software industry to navigate the challenge of improving code review ergonomics and training early-career engineers in an automated environment.

Source quotes

[0:00] Anders Hejlsberg: People love these like take it all the way to 100%, right? And that's where I get off the bus. [7:29] Anders Hejlsberg: Moore's Law has stopped giving us faster CPUs. It's giving us more CPUs, and we got to like find ways to use them in our compute-intensive workloads or else we're leaving money on the table. [17:11] Anders Hejlsberg: It very authoritatively came up with the wrong answer... because it just forgot like about some of the settlements. But if we had asked it to write a spreadsheet, which is really—that's just a program, right? Then we would have gotten the right answer because it's very good at writing programs. [21:15] Anders Hejlsberg: We weren't trying to change JavaScript; we were trying to improve JavaScript. [32:59] Anders Hejlsberg: the world needs another programming language like it needs another hole in the head. [32:59] Anders Hejlsberg: it's really never until version three that it truly starts to get okay. [43:52] Anders Hejlsberg: I wasn't getting my hands dirty. I was writing stuff in the framework and in the libraries, but... these are not like the deep, really super hard problems to solve, right? And I didn't really know it at the time, but I was gradually getting less happy with the work that I was doing... I finally realized I'm just a happy coder, you know? I mean, I like the spec stuff too, but coding is like, man, that's what gets me up in the morning, make coffee, and write some code. [47:10] Anders Hejlsberg: I'm like, what? Why? Why would you want to do that? Why don't you just write JavaScript? 'Well, because that way we can get great tooling. Then we can use Visual Studio, and we can have projects, and we can have type checking, and we can have code refactoring and navigation, and we can write interfaces and people can understand how this all works.' And I'm like, 'Wow, is JavaScript really that busted?' And you're saying like the way you want to fix that problem is by abandoning JavaScript, treating it as an instruction language, right? And then having a code generator target it. I'm like, couldn't we like fix JavaScript? Wouldn't that be better? [63:50] Anders Hejlsberg: Don't let people tell you that it can't be done. When they tell you it can't be done, it's because they can't do it. That doesn't mean that you couldn't possibly do it. [63:50] Anders Hejlsberg: Whenever we told them here's what we have, they said that can't be done. That's like, 'Nah, you guys are full of... that's like not possible,' you know. Well, it was. And I didn't know that it wasn't possible, right?

Original transcript

[0:00] Don't let people tell you that it can't [0:02] be done. [music] When they tell you it [0:03] can't be done, it's because they can't [0:05] do it. [0:06] >> This is Anders Hilesberg, the creator of [0:08] Typescript and C. And we talked about [0:10] how Typescript recently became [music] [0:12] 10 times faster through a native [0:14] rewrite. [0:15] >> Couldn't we like fix JavaScript? [music] [0:17] Wouldn't that be better? [laughter] [0:19] Do you know what I mean? [0:20] >> If you think about Rust, what didn't it [0:22] have that if it had it, you would have [0:24] picked it? [0:25] >> I mean, I think there are two things. [0:26] [music] Um, if you're going to hand AI [0:29] the keys, I mean, then all bets are off, [0:32] right? [0:33] >> Why is there such a big difference [0:34] between this opinion and what I see from [0:38] maybe people who work at Anthropic? [0:40] People love these like take it all the [0:43] way to 100%. [music] Right? And that's [0:45] where I get off the bus. [0:47] >> Here's the full episode. [0:51] The big thing that we're going to talk [0:53] about here is obviously TypeScript 7 [0:55] with the native rewrite. And the first [0:58] thing that I think of when I see this [0:59] was I didn't even realize that the [1:02] compiler was written in JavaScript to [1:03] begin with because I don't usually think [1:05] of compilers being written in you know [1:08] highle dynamic languages. [1:10] >> Yeah. No. [1:11] >> So why was Typescript written originally [1:14] the compiler written in JavaScript? [1:17] >> No, it's a good question. Uh, and [1:20] honestly, if you had told me like before [1:23] the TypeScript project started that [1:24] Anders you're going to be writing [1:25] compilers in JavaScript, I'm like, "No, [1:27] no, I'm not." But I mean it it it you [1:31] know the original prototypes for for [1:34] TypeScript um the Strata project as it [1:36] was called in the in the very early days [1:39] was actually written in C because it was [1:42] like an adapt adaptation of the the [1:45] parser the JavaScript parser that we had [1:47] in IE and whatever and and then we moved [1:50] to to JavaScript but we wrote it sort of [1:52] C style. Um but why did why did we go [1:56] with JavaScript? Well, I mean, if you [1:59] can self-host in the ecosystem that you [2:03] want to be a part of, then that is just [2:05] dramatically better than putting [2:07] yourself outside the ecosystem and [2:09] trying to target that ecosystem. Do you [2:11] know what I mean? Because by writing it [2:13] in Typescript, we were also [2:17] daily users of Typescript and daily [2:19] users of the tooling that we were [2:20] building. And whenever something didn't [2:22] work right, we knew it immediately. And [2:24] whenever something didn't perform right, [2:26] we knew it, you know. And so so in the [2:29] early in the early years, it was it was [2:31] a huge uh boon I think. And then of [2:35] course [2:37] JavaScript runs everywhere, right? And [2:38] that meant automatically our compiler [2:40] could run on every platform anywhere [2:42] even in the browser right uh had we gone [2:45] with a native code solution at that time [2:47] it wouldn't have been possible to run it [2:49] in the browser. Now we have web assembly [2:51] or wom you know but that didn't exist at [2:54] the time right um so so it was it was a [2:58] meaningful choice uh and honestly [3:02] at that time also people didn't really [3:04] realize how fast JavaScript had gotten I [3:08] mean it used to be very slow and then [3:10] Google did all of their excellent work [3:12] with V8 and got it to within two or 3x [3:16] of of native code which is pretty darn [3:18] impressive. Um, and it was like full [3:22] well possible to write compilers in in [3:25] JavaScript. Um, and you could even get [3:28] them performant. Uh, because often [3:31] it's the algorithms that determine how [3:33] performant you are. It isn't necessarily [3:34] the runtime environment, right? I mean, [3:36] it's a combo, but but yeah. [3:38] >> Is there anything unique about the [3:40] TypeScript compiler? like you know I [3:43] think of a compiler I think of clang or [3:46] or you know one of those ones that is [3:48] used for maybe C, C++ or those static [3:51] languages. What's unique about the [3:53] TypeScript compiler when it was written [3:55] in JavaScript compared to these native [3:59] uh compilers? [4:00] >> I think there are a couple of things [4:02] that are pretty unique about [4:04] TypeScript's compiler. First of all, it [4:07] doesn't target machine code. targets [4:09] JavaScript [laughter] [4:11] and and some people call that a [4:12] transpiler and in a sense you know the [4:15] the compilation phase is mostly about [4:17] removing the type annotations and [4:19] turning your TypeScript back into [4:21] JavaScript. Right now in the early days [4:24] also an important part of of the [4:27] compilation process was to downlevel [4:29] your JavaScript meaning [4:32] all of the runtime environments at the [4:34] time were not evergreen. uh and [4:36] sometimes people were lagging like [4:38] multiple years behind on which level of [4:41] the standard was implemented and for [4:43] example when classes got standardized [4:46] most JavaScript runtimes didn't [4:47] implement classes but it turns out that [4:49] you can downlevel to constructor [4:51] functions and and trans transform the [4:54] code and so part of what we did was this [4:58] transformation down level transpiling of [5:01] the code but then of course the type [5:03] checking uh is is the big thing that we [5:05] loop and the type checker in in [5:09] Typescript is also quite unlike any [5:11] other type checker uh in other [5:14] compilers. Typically type checkers exist [5:17] in compilers to guide the code generator [5:21] um because you want to know are we [5:23] dealing with a float or an in or a [5:24] string here so we can generate you know [5:26] the correct machine instructions for [5:28] that data type etc etc. That's not the [5:31] case in in Typescript. In fact, since we [5:34] erased the types, the types have no [5:36] impact whatsoever on the runtime [5:38] behavior of the code. They purely exist [5:41] for for tooling sake and for the [5:45] developer sake and to guide things like [5:48] statement completion and refactoring and [5:50] code navigation, which is a whole [5:52] different thing. Um, and also they don't [5:56] necessarily have to be there. Uh, and so [5:59] Typescript has a gradual type system. [6:01] you can sort of have half of your code [6:02] have types and the other half is just [6:04] any um that we don't check. Now very few [6:09] languages have anything like that. So, [6:13] so it's very it's a very different [6:14] compiler in in in that sense, you know, [6:16] and a very different language in in that [6:18] sense. Um, that actually made it [6:20] fascinating to work on because we were [6:22] solving problems that no one had solved [6:24] before, you know. [6:25] >> I know a lot of compilers, you know, [6:27] they take the the higher level code and [6:29] they typically apply optimizations as [6:31] well. Maybe, you know, they unroll loops [6:34] or they get rid of duplicate [6:36] instructions, simplify things. Is [6:38] anything like that happen in the [6:40] TypeScript to Java compilation process? [6:44] >> Very little. Um, like I said, when we do [6:47] the down leveling, there there's some [6:50] transformations that that that go on [6:52] that are that are complex, but it is [6:55] less and less the thing that's important [6:57] about Typescript. And in fact, a lot of [6:59] people use TypeScript only for the type [7:01] checker. uh and then they use some [7:05] bundler like ESB build or SWC or [7:08] whatever to package their app, erase the [7:10] types, do whatever needs to be done in [7:13] order to make it runnable in in in the [7:15] browser. And so we're not really there [7:18] to optimize your your code for runtime. [7:21] We're there to make you more productive [7:23] as a developer or make AI more [7:26] productive as a as a developer. [7:29] So with the the native rewrite of this [7:32] originally fully JavaScript compiler, [7:35] what was the problem you were trying to [7:37] solve with the rewrite and why did you [7:40] end up write rewriting it in native [7:42] code? [7:43] >> Well, I mean the the problem we were [7:44] trying to solve it's real simple [7:46] performance and scalability. JavaScript [7:48] was never really optimized for compute [7:52] inensive workloads like compilers, [7:54] right? JavaScript is more about creating [7:57] UI that runs in a browser. Was [7:59] originally intended for just like maybe [8:02] a 100 lines of code, but now of course [8:03] it's gotten to be a lot more. Um, but [8:06] it's not it's not a place that that you [8:09] would optimize for um for the kind of [8:13] workload that that we are. So in [8:16] JavaScript, first of all, you pay a 2 to [8:19] 3x perf penalty compared to native code. [8:22] I mean it depends on on the workload you [8:24] know but that's but if if you're doing [8:26] compute that's about where it's at. Um [8:30] and then secondly in JavaScript there [8:32] are a lot of restrictions around use of [8:34] concurrency. Uh JavaScript was always [8:38] engineered in fact to be a single [8:40] threaded language. That's why we have [8:41] callbacks and async and and and [8:43] whatever. It's because you can't spin up [8:45] threads. Um, and that's a good thing [8:49] mostly because concurrency in a language [8:52] with mutable data is very very hard [8:55] because you can have races and deadlocks [8:57] and all of this good stuff, right? [8:58] That's why functional programming [9:01] languages are easier with concurrency [9:03] because all the data is immutable and [9:05] it's much easier to reason about. Um [9:09] so JavaScript doesn't give you access to [9:12] concurrency other than web workers and [9:15] but web workers can't share data between [9:18] each other other than by remoting it. So [9:20] you can you can have one web worker [9:22] compute some something, but if it wants [9:24] to give it to some other web worker, it [9:26] has to turn it into JSON or it can't [9:29] just hand it objects. And that means you [9:32] can't have one worker compute some data [9:36] structure and then have someone else use [9:38] it. In other words, you can't have [9:40] shared memory concurrency. And really [9:42] that's what we wanted in order to gain [9:46] all of the perf that we were leaving on [9:48] the table by not utilizing multi-core [9:50] CPUs that everyone has today, right? [9:53] Because Moors law has stopped giving us [9:56] faster CPUs. It's giving us more CPUs [9:59] and we got to like find ways to use them [10:01] in our in our compute intensive [10:02] workloads or else we're leaving money on [10:04] the table. And so we were leaving money [10:05] on the table in multiple ways, right? [10:08] And so native code and that was why we [10:11] we looked for a language that [10:15] would get us out of both of those binds. [10:17] It had to be native and it had to have [10:19] access to shared memory concurrency. [10:21] >> I saw for the language choice you went [10:23] with Go. And when I think of all the [10:26] systems languages, the ones that are [10:28] often hot or maybe you know Rust or [10:31] Zigg, why did you choose Go for the [10:34] native rewrite? I think the decision [10:36] process was actually pretty structured. [10:39] You know, the first decision we made was [10:43] we're not going to rewrite. We're going [10:44] to port because only by porting can we [10:48] preserve the semantics and the [10:49] algorithms and the exact behavior of our [10:52] existing compiler which everyone depends [10:55] on for backwards compatibility. Now we [10:57] could have we could have cleaned the [10:59] slate and started completely from [11:01] scratch but we would have come we would [11:02] have come up with a different language [11:04] in the sense that it would give you [11:06] different errors or behave differently [11:07] in certain situations where it has to [11:09] make choices between multiple [11:12] possibilities and and what have you. [11:14] Right? So we wanted to port and that [11:17] meant our code makes certain assumptions [11:21] like our code for example assumes the [11:23] existence of garbage collection. It [11:26] assumes the existence of first class um [11:31] uh treatment of functions. You know, you [11:33] can have functions within functions and [11:34] you can close over over out of state and [11:36] so forth. Um and as we evaluated all of [11:40] these, [11:42] Go was was the one that checked the most [11:44] boxes. You know, it gives us it gives us [11:48] very robust and mature native code [11:51] generation on all major platforms. it [11:54] has garbage collection and it has access [11:58] excellent access to shared memory [11:59] concurrency. Um, and those were like the [12:02] high order bits that we wanted to check [12:04] and every other language had something [12:08] that kind of worked against those [12:10] objectives. So for this particular [12:12] workload, Go was the right was the right [12:13] choice for us and it's worked out well. [12:16] >> If you think about Rusk, what didn't it [12:19] have that if it had it, you would have [12:21] picked it? I mean I think there are [12:23] there are there are two things um it [12:26] doesn't have uh garbage collection [12:29] it's done manually you know uh well or [12:33] it's done through the borrow checker but [12:35] the borrow checker doesn't allow [12:36] circular data structures and our [12:39] compiler is chalk full of circular data [12:42] structures we have trees with parent [12:43] pointers we have types that are [12:45] recursive we have symbols that refer I [12:47] mean it's everywhere and like I said if [12:50] we had chosen to rewrite we could have [12:52] probably solved all of that, but it [12:54] wouldn't have been just porting the [12:56] code. It would also have been like [12:57] solving a whole bunch of new problems [12:59] that we had bought ourselves by by going [13:01] that route. We tried [laughter] [13:04] and it just wasn't feasible, you know, [13:07] uh and and and so so we were we were [13:09] just trying to optimize for, you know, [13:12] doing as little work as possible to get [13:14] us to the payout, which is which and [13:18] honestly, Rust is no better when it [13:20] comes to like the quality of the [13:22] generated code or the or the the [13:24] concurrency gains that we could have [13:25] gotten out of it. [13:27] Go just as it's great. I mean, so so we [13:31] got we got all the bennies with for less [13:33] work by by going that route. [13:35] >> I know some languages they're when you [13:37] say they're garbage collected, they [13:40] >> there's something in the the language [13:42] itself that is doing garbage collection, [13:45] but um there's also independent [13:48] libraries that can provide garbage [13:50] collection, right? [13:52] There is, but it it but it comes often [13:55] with a whole bunch of restrictions and [13:57] and and it doesn't come necessarily with [14:00] the safety guarantees that we were [14:02] looking for. I mean, like Go is type [14:04] safe and memory safe. uh meaning that [14:07] you don't get to just like have stray [14:10] pointers or or whatever where Rust you [14:13] can do ref counting or you can do you [14:15] can do all sorts of different strategies [14:17] but there's always like that little bit [14:20] of unsafe where you have to like do this [14:22] in order to make it all work you know uh [14:25] where where if garbage collection is [14:28] engineered into the language it really [14:30] is a a separate concern that is you you [14:33] you don't you don't have to do anything [14:35] special in I mean of course you you have [14:39] to like not hold on to data that you no [14:41] longer need and whatever you know but [14:43] that's true of ref counting as well [14:45] right but but it is inherent in in the [14:48] language [14:49] when you ported it from JavaScript to go [14:52] I'm curious how much LLMs were used in [14:55] that process because I know famously [14:58] there's some major projects that have [15:00] been doing uh rewrites of their entire [15:03] codebase I know there's this JavaScript [15:05] project called bun [15:06] >> that rewrote everything from Zigg into [15:09] Rust and so [15:10] >> seems like a pretty useful tactic and [15:13] I'm curious if you leverage that in this [15:16] process. [15:16] >> Not a whole lot but it also has to do [15:18] with timing. Uh we started this project [15:21] two years ago and two years ago LLMs [15:23] were nowhere near as good as they are [15:25] now. I mean that's how crazy fast it [15:27] it's all moved, right? Um, [15:31] so what we did though is we we certainly [15:34] had [15:36] a bunch of tools that aided us in the in [15:39] the in the the port. I'd say the [15:42] prototypes we wrote, the scanner and the [15:43] parser we wrote manually. Um, and at [15:47] that point we could convince ourselves, [15:49] wow, we can actually get 10x out of [15:51] this. Now what do we do with the rest of [15:53] this codebase? And what we did was we [15:56] wrote a tool that syntactically [15:58] translates TypeScript into Go. [16:03] This Go that comes out of it, it has no [16:05] syntax errors in it, but it doesn't [16:06] compile either because it's full of, you [16:09] know, like it uses types as if they were [16:12] TypeScript, which they're not in Go. And [16:14] so all of that had to be refactored. We [16:17] had to redo all the data structures or [16:18] whatever, but we got the same code base [16:21] out of it. And then we can sort of bang [16:23] on that. and then in a more localized [16:25] fashion maybe use AI occasionally to [16:28] help us do the transformation. So it was [16:30] sort of manual and automated [16:34] and a little bit of AI. Now if we were [16:38] to start the project today would we do [16:41] it differently? Possibly. Um although I [16:43] will say if if we just let AI loose on [16:48] you know what is it like half a million [16:49] lines of code that we have in the old [16:50] compiler or somewhere between half a [16:52] million and a million right uh and asked [16:54] it to translate it all. Well I don't [16:57] know that that would absolve us from [16:58] then having go in and carefully [17:00] examining every line that came out of it [17:02] to make sure that there were no [17:03] hallucinations. Right? Unless you have [17:05] 100% perfect test coverage, you probably [17:08] still got to go check all of that. Now I [17:11] think a a a better approach quite [17:14] honestly would be enlist AI to write a [17:17] program that helps you translate from [17:20] Typescript to Go because at that point [17:23] you can park the stochasticness in that [17:25] program and then you can get [17:27] deterministic behavior whenever you run [17:29] the program which means you get the same [17:31] transformation every time you run it [17:34] right that's always the thing about AI [17:36] that people forget it's not [17:37] deterministic right so you can't really [17:40] trust that it's going to do the same [17:41] thing twice. [17:43] Um, [snorts] [17:44] so, so we might have done it that way, [17:47] but AI was not ready to do it at the [17:49] time. Now, that doesn't mean that we [17:50] don't use AI. I mean, like now down the [17:53] line, we use AI a lot in our in our [17:56] internal processes around like the the [17:58] compiler as everyone does, right? Like [18:00] help it to write tests and to move pull [18:03] requests and what what what have you. [18:05] and and whenever an issue is logged, we [18:08] first thing we do is put copilot on and [18:09] see if it can fix it for us, right? I [18:11] mean, and so yeah, [18:13] >> in that approach where you you use the [18:15] LM to generate uh tooling and then you [18:19] know the tooling is deterministic, [18:21] >> but you'd still have to validate that [18:23] thing. [18:23] >> Yes. But that's that's a lot smaller [18:25] surface area that you have to validate, [18:27] right? And honestly, I I've seen that [18:30] even with friends that are like we did [18:32] some trip together and there was like [18:34] some some accounting of they go, well, [18:36] he paid for the hotel rooms or we paid [18:38] for this and whatever and we needed to [18:39] like sort it all out, right? And so, so, [18:42] okay, well, here's what all the costs [18:43] were and here were the pie and like have [18:45] AI fix it for us, right? Or like tell [18:47] who owes who what and it very [18:50] authoritatively came up with the wrong [18:52] answer, right? [laughter] [18:54] Because it just forgot like about some [18:57] of the settlements, right? And but if we [18:59] had asked it to write a spreadsheet, [19:02] which is really that's just a program, [19:03] right? Then we would have gotten the [19:05] right answer because it's very good at [19:06] writing programs. So it's kind of funny [19:09] how you you you don't sometimes you you [19:12] don't ask AI for the for the answer. You [19:14] ask it for a program that computes the [19:16] answer. [19:17] >> What are the potential benefits that you [19:20] left on the table by doing a port [19:21] instead of a full rewrite? [19:23] >> To be honest, I don't think there are [19:25] any. Um, and I don't think we would [19:27] consider uh a rewrite. We were quite [19:29] happy we're quite happy with the way [19:31] this codebase works. Uh, and we're and [19:34] we certainly I don't think we're leaving [19:36] any any money on the on the table [19:38] currently. Um, and and as I said [19:41] earlier, rewrites are toxic often for [19:44] ecosystems because they sacrifice [19:47] compatibility because you never rewrite [19:50] and you get you never get back to [19:52] exactly what you had before, right? Oh, [19:54] but oh, but in the name of making it [19:56] better or prettier or whatever, we [19:57] change this and that and this and that [19:59] and the other, right? And then well, all [20:01] the users get to suffer through that, [20:03] right? So, so backwards compatibility is [20:05] super important if you want to keep your [20:08] ecosystem happy. Uh, and and and we we [20:10] do want that. [laughter] [20:12] In studying for this interview, I I just [20:15] keep reading about JavaScript and the [20:17] the strange semantics of the language. [20:20] And I think throughout my career too, [20:22] people have typically [20:24] not been super satisfied or happy with [20:27] JavaScript for some reason or the other, [20:29] >> right? [20:30] >> And my question is why is it so popular [20:34] despite that? [20:36] >> So first of all, I I don't think [20:38] JavaScript is as bad of a lang of a [20:40] language as as some people make it out [20:42] to be. I I I will say in in like the [20:44] three about three four weeks that [20:46] Brendan Ike had to create this language [20:48] back in the mid 90s, he did a lot of [20:51] things right. Um and thank God that he [20:54] had been educated on functional [20:55] programming and and got first class [20:58] functions done right where you can have [21:00] functions within functions and the inner [21:02] functions can access the outer function [21:04] state and you can pass functions around [21:07] as first class values. [21:10] that is super powerful and JavaScript [21:12] actually got that very right. Um, now [21:15] there's some quirks in the language too, [21:18] like all of the automatic conversions [21:20] and all of the bizarre differences [21:22] between double equals and triple equals [21:24] are just like drives everyone mad, [21:27] right? But that's exactly what type [21:28] checkers are happy to do. They can like [21:30] they can far it out all the little [21:32] differences because they understand the [21:34] all the deep semantics of the language [21:36] that no one seems to be able to keep in [21:38] their mind, right? So, and I think [21:40] that's part of why Typescript has become [21:42] so popular, right? It's like it can [21:44] actually like truly bring out the best [21:46] parts of JavaScript uh and leave the bad [21:49] stuff behind. And of course, you can't [21:52] like like the thing about JavaScript is [21:55] it is the crossplatform language. Like [21:58] even Java that was engineered and [22:00] intended to be the way to write [22:02] crossplatform applications, it's not [22:04] really crossplatform. It doesn't run in [22:07] the browser, you I mean it doesn't it [22:09] doesn't run everywhere, right? [22:10] JavaScript runs everywhere. Um, so there [22:15] are a lot of there are a lot of reasons [22:16] why you should like JavaScript and and [22:20] with TypeScript, I think we've managed [22:22] to sort of capture all the badness and [22:25] park it. [22:27] I saw there were some projects. I don't [22:29] know if you're familiar with Dart or [22:32] CoffeeScript and [22:34] >> it seems like these were some effort to [22:37] replace JavaScript or improve it and [22:40] >> right [22:41] >> but they're not popular today. So I'm [22:43] curious what happened. [22:44] >> I mean I think coffecript was mostly [22:49] it's a different syntax for JavaScript. [22:51] So, so it doesn't really change the the [22:53] semantics and it doesn't it didn't [22:55] provide any additional tooling and and [22:57] whatever. And and Dart was also in a [23:00] sense about fixing JavaScript, right? [23:03] But if you can fix something by fixing [23:06] it instead of trying to replace it with [23:09] something else, then you're doing the [23:13] ecosystem a much bigger favor, I think. [23:16] Right. And that's what we set out to do [23:18] with TypeScript. We weren't trying to [23:19] change JavaScript. we were trying to [23:21] improve JavaScript. Um, and I think [23:24] that's ultimately why we why we [23:26] succeeded. [23:28] >> I mean, in this new age where it's very [23:31] feasible that maybe AI could rewrite [23:34] code bases, [23:36] um, I imagine people will start to go [23:39] towards the the desired languages rather [23:42] than the ones that are the incumbent [23:43] languages. [23:45] And I'm curious if you think that [23:47] JavaScript might become less used in the [23:49] future. [23:51] >> See, I I don't think so. I I what I've [23:54] observed is that AI [23:58] is best at the languages if seen the [24:01] most of in its training set, right? And [24:04] AI gets trained on all the code that [24:06] exists in the world. Um, [24:09] which means there's an awful lot of [24:11] JavaScript, an awful lot of TypeScript, [24:12] an awful lot of Python. And therefore, [24:15] AI is good at JavaScript and TypeScript [24:17] and Python. And it is less good at my [24:20] favorite little language that I just [24:22] invented. In fact, there's none of it in [24:23] the training set, which means you have [24:25] to sacrifice God knows how many tokens [24:27] in the prompt to teach AI the language [24:31] before you can even ask it a question [24:33] about the language. Do you know what I [24:35] mean? So in that sense I think incumbent [24:38] languages are actually if anything going [24:41] to flourish uh because of AI and we're [24:44] sort of seeing that right now with with [24:45] TypeScript too right there there's a [24:47] noticeable knee in the curve of [24:49] TypeScript adoption that coincides with [24:52] the advent of AI. I do think the [24:55] incumbent languages are actually if [24:57] anything getting stronger. [24:59] >> What percent of all JavaScript is [25:02] written in Typescript? [25:04] Well, so, so in the last year, [25:08] Typescript uh became the number one used [25:11] language on GitHub. Um, so there's [25:14] JavaScript more than JavaScript. [25:16] >> So, so more than 50% on GitHub at least [25:20] >> is is is written in in Typescript. Um, [25:23] so so we're actually like larger now [25:25] than the language that we set out to [25:27] improve. [25:28] >> Wow. [25:29] >> Yeah. And larger than Python. If you [25:32] were to just draw that out in the [25:33] future, do you think that eventually [25:35] TypeScript would become the default and [25:37] almost 100% of all JavaScript would be [25:40] typed? [25:41] >> Well, certainly, I mean, if you're [25:43] having AI write it, I I almost challenge [25:46] you to find a tool that writes [25:48] JavaScript. They all write TypeScript. [25:50] Uh because it helps AI write better code [25:53] because the type annotations guide the [25:56] LLM towards writing or to write making [25:59] fewer mistakes. and the ability for us [26:02] to statically validate the code before [26:06] you run it. I mean, that's the [26:08] distinction, right? The only way you can [26:09] validate JavaScript is by running it, [26:12] which means you have to set up a runtime [26:14] environment, which might not be possible [26:16] for AI to do because AI lives in a [26:18] sandbox, right? But AI can run through [26:21] tools, the compiler, and check the code [26:24] that it just generated and be told, "Oh, [26:26] you made a mistake. Oh, well, let me fix [26:28] it then before I even tell anyone that I [26:30] made the mistake, right? [laughter] [26:32] [snorts] [26:32] >> After learning about the this 10x [26:35] improvement in performance from uh [26:37] rewriting in native, I makes me wonder [26:40] why anyone would use JavaScript on the [26:44] back end. Why not just always use native [26:47] languages on the back end? [26:48] >> Well, it depends on your problem. Uh I [26:51] think because the thing that that [26:52] overlooks is [26:55] what kind of thing am I going to write [26:56] on the back end, you know, like like [26:58] there are an awful lot of very very good [27:02] web server frameworks for example that [27:04] that use TypeScript or JavaScript, [27:07] right? So, so if there are like [27:10] frameworks in your ecosystem that gets [27:11] you to a solution quicker than if you [27:14] had to write that because your native [27:16] language wasn't really intended to [27:18] target that particular community. So, I [27:22] think it very much depends on [27:25] your what what your problem is [27:27] affinitized with. Um, and and often PF [27:31] of your code isn't the bottleneck. I [27:34] mean, like look at Python. I mean right [27:37] it's it's used to basically script and [27:39] all of the LLM training in in the world [27:42] right I mean which clearly a lot of that [27:44] code is ultra timer critical uh but [27:47] that's written in native code right and [27:49] then you use Python as the orchestration [27:51] language and in a sense in a web server [27:53] you know like TypeScript is just an [27:55] orchestrator you know of talking to a [27:58] database and doing this and that what [27:59] and and and the things that the things [28:01] that that ultimately control the [28:03] performance of applications like that [28:05] aren't necessarily [28:07] whether that inner for loop is running [28:10] as as as native code or not which [28:13] actually it is because of the JIT anyway [28:15] right I mean so [28:18] I mean measure measure first and then [28:22] make decisions right because you always [28:24] get surprised when you measure [28:26] >> when you talk about how much faster it [28:28] was too one of my immediate thoughts is [28:31] why wasn't it done sooner [28:33] >> you know at the time we started [28:35] TypeScript script. I don't know that we [28:37] had ever envisioned that people would be [28:39] writing projects that are the size of [28:42] the projects that people are now writing [28:44] in Typescript, right? Like Visual Studio [28:47] Code is like 2.3 million lines of code. [28:50] I mean, we have in in-house projects [28:52] that are over 10 million lines of of of [28:55] code, which is insanity. We would have [28:57] just at the time gone, well, that's [28:58] clearly no one's ever going to do that, [29:00] right? But that was a decade ago or more [29:02] than a decade ago, right? We started in [29:04] 2012 with the TypeScript project and the [29:06] world looked very different and so [29:08] gradually people have started writing [29:11] larger and larger and larger projects, [29:13] right? And at the same time, our [29:16] compiler has gotten smarter and smarter. [29:18] We've added all sorts of cool features [29:20] like union types and discriminated [29:22] unions and control flow analysis and [29:24] blah blah blah. And all of these things [29:28] make our type checking even better, but [29:30] it also makes it go a little slower [29:32] every time we add a new feature. Right? [29:33] In fact, our TypeScript 6 runs only [29:35] about 50% of the speed of TypeScript 1.5 [29:39] for example. But TypeScript 1.5 also did [29:42] a whole lot less. Um, so projects have [29:46] gotten bigger and the compiler does [29:48] more. All of which [laughter] [29:51] detract from your effective output. And [29:53] as I mentioned, Mors law also [29:56] unfortunately stopped delivering faster [29:58] CPUs and JavaScript keeps you from [30:00] taking advantage of the additional [30:02] cores. And it's not clear that we could [30:04] have foreseen all of that, right? But [30:07] but but it's just the way it panned out, [30:10] right? [snorts] [30:11] >> Open AAI, Enthropic, Curser, and [30:14] Verscell all use this product to make [30:16] their lives better. And the problem it [30:18] solves is when you're building SAS or an [30:20] AI product and you want to sell to other [30:23] companies, there's all these [30:24] requirements you need to meet. There's [30:26] SSO, there's skim, there's arbback, [30:29] there's audit logs. These are all things [30:31] that take time to integrate but aren't [30:33] the main focus of your app. Work OS is [30:36] an API layer that lets you meet all of [30:37] these requirements in just a few lines [30:40] of code. So let's say you have a new SAS [30:42] product and you want to sell to other [30:44] companies. work OS will solve all of [30:46] these critical feature gaps for you. You [30:49] can check them out at workos.com to [30:51] learn more and get started. And I [30:53] appreciate them for supporting my work [30:55] and sponsoring this podcast. Jira by [30:58] Atlassian isn't just for tracking work [31:00] anymore. Now you can pick your favorite [31:02] AI agent to assign tasks to and they'll [31:04] get access to the rich context that's [31:06] already in Jira. When the agent is done, [31:09] it surfaces a pull request. That way you [31:11] can get more done with your favorite [31:13] agents all in one place. Learn more at [31:16] jira.dev. That's jir.dev. [31:20] Appreciate them for sponsoring the [31:22] podcast. And back to the show. When I [31:24] first became a software engineer and I I [31:27] went to start working at Facebook at the [31:29] time, they had this popular framework [31:32] called Flow, which was [31:34] >> doing type inference on top of [31:36] JavaScript. It was this thing that would [31:38] take a long time. [31:39] >> Yep. And then I' I'd never hear about it [31:41] these days. So it sounds like Typescript [31:44] won if there was a competition to [31:46] typing. [31:47] >> There was a bit of it. Yeah. In in in [31:49] the early days. Um I think the thing [31:52] that worked for us was actually the fact [31:54] that we were self-hosted which made it a [31:57] lot easier for the community to [31:58] contribute to the project. [snorts] [32:01] Flow was written as I recall in camel. [32:04] Um, and so in order to contribute to [32:07] flow, you had to go learn a whole [32:09] different way of programming and and in [32:11] a in a different language, right? And [32:13] Float also didn't really focus all that [32:15] much on [32:17] IDE based tooling, [32:20] which we knew full well going in. We're [32:22] writing a compiler, but we're not [32:23] writing a compiler in order to generate [32:26] machine code. We're writing it to make [32:27] better tooling. That was why we wrote [32:30] it, you know, and so right there [32:33] handinhand with our compiler, we had a [32:35] language service. It was deeply [32:36] integrated into Visual Studio, Visual [32:38] Studio Code, all sorts of other editors [32:40] through an open protocol, you know, and [32:42] that just that's where that was the [32:46] problem that needed solving, right? I [32:48] mean, it's not it's it's nice to have a [32:50] type checker, but boy, you you want [32:52] that. You also want statement [32:53] completion. You wanted red squiggies. [32:55] You want like I mean, you want it [32:57] interactive, right? [32:59] So I know in your career you've you've [33:01] worked on uh multiple programming [33:03] languages. What does it take to build a [33:06] programming language? Well, first I'll [33:09] say that the world needs another [33:11] programming language like it needs [33:12] another hole in the head. I mean it it's [33:14] it's like you you kind of got to be a [33:16] certain [laughter] kind of of person to [33:20] to even embark on it to begin with, [33:22] right? It's a super fascinating area of [33:25] of computer science and it's one that's [33:27] been around ever since the beginning of [33:29] of of computers. Now, every compiler, [33:33] every language has a whole bunch of [33:35] things you need to to understand like [33:37] parsers and scanners and lexers and code [33:39] generators and and and and whatever, [33:41] right? But but that's sort of the [33:44] mechanics of implementing the language. [33:46] And then there's the design of the of [33:49] the language, sort of the art of making [33:53] it feel right and whatever, right? And I [33:55] I think you sort of have to master both. [33:59] And then you also got to appreciate that [34:01] like every new language is actually only [34:03] 10% new and then it's 90% the same [34:06] drudgery that every other language has [34:08] to go do. And so be prepared for a lot [34:11] of work that maybe isn't as interesting, [34:14] you know. [34:16] And then finally maybe I'll say that you [34:19] know like never forget there that you [34:21] you stand on the shoulders of giants. I [34:24] mean you you in order to make a great [34:26] programming language you got to [34:27] understand a bunch of other programming [34:28] languages first uh and understand all [34:31] the all the distinctions between the [34:33] different styles of programming like [34:34] procedural and object-oriented or [34:36] functional or what have you. Um [34:40] and then last but not least it's like [34:43] it's a long game. I mean, it is probably [34:45] a longer game than anything else. I [34:47] mean, like every language project I've [34:51] worked on, I've worked on each of them [34:53] for at least 10 years. Um, and shipped [34:57] multiple versions, and it's really never [34:59] until version three that it truly starts [35:02] to get okay. Do you know what I mean? [35:05] And, and it just takes an incredible [35:07] amount of devotion to to that. So, you [35:09] got to really not be the type that tires [35:11] of a problem quickly and then moves [35:13] along. that you're not meant to do [35:14] language design. [35:17] And you see that too if when you talk to [35:19] language designers in the industry, [35:20] they've been doing it for a long time. [35:22] >> You mentioned those two parts. There's [35:24] the the objective pieces that you need [35:28] to implement and then there's the the [35:31] art of the design and making the [35:32] language I guess ergonomic for [35:35] developers. When you think of that [35:37] second part, that art [35:39] >> and you look at other programming [35:41] languages, are there any that you admire [35:43] outside of the ones that you've worked [35:45] on? Of course, [35:47] >> learning and and and fully appreciating [35:49] the beauty of functional programming has [35:51] has been very educational, right? I [35:54] mean, because it really is a different [35:55] way of thinking about programming, a way [35:58] of thinking of programming that's much [36:00] closer to math than it is to [36:04] machines. Um, [36:07] and I think there's there's a lot of uh [36:10] incredible goodness that has come from [36:12] that. And and honestly even in in like [36:14] like building the TypeScript project uh [36:17] large portions of the TypeScript [36:18] compiler are written in a highly [36:20] functional style um and work on [36:23] immutable data structures that are then [36:25] now because of shared memory concurrency [36:27] can be shared between different [36:32] uh threads or processes that don't [36:35] mutate the data and therefore they can [36:37] share one data structure. Right? And [36:39] that's incredibly powerful. But [36:41] mastering this, you know, like writing [36:43] islands of pure functional programming [36:46] inside an imperative program and ma and [36:48] and and putting it together with [36:50] concurrency. I mean, it's it's it's [36:51] complex, but I think functional [36:53] programming has brought a lot to the [36:54] world. Um, I know object-oriented [36:56] programming as well. I mean, but I [36:58] wouldn't single out any particular [37:01] language. Every one language you you [37:03] come in contact with, you learn [37:05] something. You know, [37:07] >> you mentioned the world doesn't really [37:10] need more programming languages and uh [37:14] if you think 10 years from now, do you [37:16] think there'll be less programming [37:17] languages than there are today? [37:19] >> It's hard to say. I mean, but like I [37:22] said, [37:24] AI tends to favor the incumbents, right? [37:28] And I I do think and I I think this has [37:30] been true even before AI. The bar keeps [37:33] going up for what it takes to [37:36] successfully implement a programming [37:38] language and create an ecosystem around [37:40] it. I mean it used to be oh you just [37:42] need a compiler. [37:45] Well [37:46] you also kind of need tooling now. I [37:48] mean you need a language service you [37:50] need uh you need debuggers. You need [37:52] profilers. You need frameworks and [37:54] libraries. You need code generators that [37:58] can target all sorts of I mean it's like [38:02] it just keeps getting harder and harder [38:04] uh you know to to to get all the way [38:07] there. [38:08] >> Well, when you think about all those [38:09] pieces that really they're all for the [38:13] people or I mean the you know the IDE [38:16] and the types and I mean the the [38:19] computer looks at that too but it's so [38:22] that we can read source. [38:24] Maybe one day the LMS will generate [38:27] machine code directly. I wonder. Um [38:32] I think [38:35] I think LLMs are better at what they do [38:39] when when they don't have to repeat [38:41] themselves a lot. I I I think like [38:46] when a program is expressed in text, it [38:49] is closest to its sort of ultimate [38:54] condensed meaning and representation, [38:57] right? If you translate it into machine [38:59] code, there's an awful lot of noise in [39:01] that machine code. Like all of the [39:03] instructions, like half of the [39:04] instructions are memory addresses that [39:06] have absolutely no bearing on what's [39:08] going on here, right? So half of it, [39:10] half of all the data is noise already, [39:12] right? And then whichever register you [39:14] pick, well, that doesn't matter either [39:15] in the code generator. And honestly, you [39:17] could change your mind at any point in [39:18] time. So, so teasing the truth out of [39:21] that noise is a lot harder than if you [39:26] just have a program where the variable [39:27] is called I and whatever. And by the [39:29] way, that you can relate to the written [39:32] instruction that the user just gave you. [39:34] I mean, keep in mind that that like AI [39:36] are they're just emulators of humans in [39:39] a sense, right? I mean, they they it's [39:41] like neural networks, right? There's a [39:42] reason we have programming languages [39:44] because we're terrible at writing [39:46] machine code straight off. out of our [39:49] head, right? AI is not that different [39:51] from us, you know? So, the same would [39:54] probably be true there. when you look [39:57] back on working on C and you know [39:59] TypeScript and these language projects [40:02] they were long journeys and I think you [40:04] know one thing people might want to know [40:06] is what did you learn through those [40:09] journeys that if you knew at the [40:11] beginning of when you embarked on [40:12] working on them you you might have been [40:16] better off [40:19] gosh well each journey is is different [40:23] uh I mean like the first project I [40:25] worked on turbo Pascal. I I think [40:30] that project started back in the old [40:32] days when it was 8-bit micros and 64k of [40:34] memory and one person could do [40:36] everything themselves and have ultimate [40:39] control of everything. And so I was very [40:41] much a one-man shop, right? But that [40:45] quickly was not scalable, right? And and [40:48] and capacities of machines. So we went [40:50] for 64 to 640K and then then kaboom the [40:53] the the the lid went off, right? and you [40:54] could have as much memory as you wanted [40:56] and so not one person couldn't do it and [40:59] I had to learn to become a team player [41:02] right and that that was a big journey [41:05] for me I mean to learn to let go right [41:08] if you're a perfectionist that that that [41:10] could be hard but that's one thing that [41:12] I would say I learned there [41:14] >> well another way to word this question [41:16] is you know what's the most common [41:18] mistake that you see people make when [41:20] they embark on building a programming [41:22] language [41:24] Well, I think people tend to overindex [41:26] on one idea, you know, that that they [41:29] have that they think, "Oh, wouldn't it [41:30] be cool if my language could do blah, [41:33] and then they underindex on all of the [41:35] mundane stuff that every programming [41:38] language has to do, you know, and then [41:40] it ends up doing that one thing they [41:41] love maybe better, but then it does [41:44] everything else not as good." [laughter] [41:47] And and and the net is a detractor, [41:50] right? And so it's so hard to convey how [41:55] many things you have to do that really [41:57] doesn't have anything to do with the [41:59] problem you're you're trying to solve [42:02] per se, you know, when you're [42:04] implementing programming languages. [42:06] >> And when you were working on C, do you [42:08] keep tabs on the other languages and [42:11] >> you know what they're doing better, what [42:13] you could do better with C? [42:15] >> Yeah. No, you got to keep yourself [42:16] informed about because like I said, we [42:19] all stand on the shoulders of giants, [42:21] you know, no other no programming [42:23] language was ever created in in in [42:26] perfect isolation, right? Everyone [42:28] learns from from everyone and then [42:30] someone comes up with a good idea and [42:32] then you see it adopted elsewhere and [42:33] we've adopted many ideas from functional [42:35] programming you know in C for example [42:38] and then other languages have adopted [42:40] some of the good ideas we had in C# like [42:42] async you know now is in JavaScript and [42:44] in some of the other programming [42:45] languages out there and that was [42:47] pioneered in C and so you know it's it's [42:50] we all learn from each other um and and [42:53] that's how the industry moves forward [42:56] really You mentioned the I guess [42:59] learning to let go. I think that's [43:00] something that a lot of people as their [43:03] career advances they they start with you [43:06] know individual contributor work and [43:07] then later they start delegating things. [43:10] >> How did you learn that or what was the [43:12] is there like a maybe a story or [43:14] particular project where you you let go [43:17] and you you kind of develop that skill? [43:21] Well, it's it's almost like I got a [43:23] counter story to the to the letting [43:24] letting go there because in the C [43:28] project um my main function was not [43:31] implementing the the C# compiler. It was [43:34] being the language designer and writing [43:35] the spec and designing all the new [43:37] language features. And [43:42] before that when I when I had worked on [43:44] Turbo Pascal, I was I was doing a bunch [43:45] of active coding, you know, on on the [43:48] thing itself, right? But then I sort of [43:50] let go of that. But I let go of it too [43:52] much and I sort of drifted up into the [43:55] stratosphere and became more of an [43:57] architecture astronaut. Do you know what [43:59] I mean? And and and I wasn't getting my [44:01] hands dirty. I was writing stuff in the [44:03] framework and in the libraries, but it [44:04] was it didn't quite these are not like [44:07] the deep really super hard problems to [44:10] solve, right? And and I didn't really [44:12] know it at the time, but I was gradually [44:14] getting less happy with with the work [44:17] that I was that I was doing, right? I [44:19] mean, it's I still enjoy, but there was [44:21] something missing, right? And so when [44:23] when this TypeScript opportunity came [44:25] along, I decided to jump in and actually [44:28] actively participating writing compiler [44:30] and it brought so much happiness to my [44:32] life. Like I I I I finally realized I'm [44:34] just I'm just a happy coder, you know? I [44:37] mean, I like the spec stuff too, but but [44:40] coding is like, man, that's what gets me [44:42] up in the morning, make coffee, and [44:43] write some code, you know? That's that's [44:45] that's that's when I'm my in in my happy [44:48] space, you know. [44:50] you know, when people are at these [44:51] really really high levels, they're kind [44:53] of have this expectation of a certain [44:55] level of impact. And so, how do you [44:58] continue to write code at as such a high [45:01] level engineer? [45:02] >> Well, the specific code I'm writing [45:06] isn't necessarily having all all that [45:08] impact, but it's it's the fact that I [45:10] also do the architectural guidance, you [45:14] know, as part of a a group of people, [45:16] right? in a in a project, you know, [45:18] there's plenty of work for everyone to [45:19] go around and then you you just but you [45:21] you you stay involved in a corner of the [45:23] project because then you see what [45:25] happens in the code, you know, when [45:27] you're checking in your code, you go, [45:29] what was what what was that over there? [45:31] Let let me just what what's happening [45:32] over here, you know, or or you realize, [45:35] oh, we need to refactor this. This this [45:36] is not this is not feeling right [45:38] anymore. Or if if but if you let go of [45:41] that you don't really you can't really [45:43] talk about the thing that people use [45:46] day-to-day. You can talk about the [45:47] syntax of the thing that people use [45:49] day-to-day but you can't talk about that [45:50] thing you know so [45:54] so both are important I think and I'm [45:56] happy that I get to do both now I know a [46:00] lot of companies have this idea of [46:01] engineering archetypes or the the way [46:04] that highle engineers get some work done [46:07] and you mentioned architect for instance [46:10] a lot of companies have different words [46:11] for architect I'm not sure if you're [46:13] saying it's just your working style or [46:16] are you saying that all high level [46:18] engineers should be hands-on at some [46:21] level. [46:22] >> No, I I'm not saying that because I [46:24] don't think it's it's like I made a [46:26] conscious choice to [46:28] remain an independent uh contributor as [46:31] opposed to become a manager. I mean, I [46:33] had plenty of opportunities um but but [46:36] it that is not where I do my best work, [46:39] right? So I think you have to decide for [46:41] yourself what is it that motivates you, [46:44] makes you happy, keeps you doing this [46:46] for for a lifetime. Do do you know what [46:49] I mean? And and and you only get one run [46:52] at it in in life here, you know? And so, [46:54] and if you're going to do your best [46:56] work, do the thing that that makes you [46:58] the most happy, I think, is and and [47:01] that's what I [47:04] learned, you know, along the way there, [47:06] that coding is part of that, a big part [47:08] of that. [47:10] >> So then when you were working on C, but [47:12] before Typescript, like how did you know [47:15] something was missing? [47:16] >> I just knew something. I I I I don't [47:18] know how I mean it it just I would I [47:20] just wasn't feeling as fulfilled with [47:23] with with the with only doing the design [47:26] part, right? I I I missed the coding. [47:28] And whenever I had a chance to write a [47:31] little bit of code, I would feel a lot [47:33] happier and I go, it's kind of [47:34] interesting. I mean, do you know what I [47:36] mean? But now I got to go write some [47:37] more specs, you know? [laughter] [47:41] >> So then, uh was Typescript something you [47:43] kind of went towards because you wanted [47:46] to write more code? I went towards it [47:47] for for many reasons. I mean it wasn't [47:50] specifically that to begin with. I I [47:52] just found the problem fascinating, [47:54] right? I mean because the way Typescript [47:56] came about was [47:58] actually indirectly through C because [48:01] the outlook.com team I think it was [48:04] approached the C group and asked whether [48:07] we would pretty please productize [48:09] something called script sharp. And [48:11] script sharp was this thing that took C [48:14] and transpiled it into JavaScript so you [48:17] could run it in a browser. And I'm like [48:20] what? Why? Why would you want to do [48:23] that? Why don't you just write the job? [48:24] Well, because that way we can get great [48:26] tooling. Then we can use Visual Studio [48:29] and we can have projects and we can have [48:31] type checking and we can have code [48:33] refactoring and navigation and we can [48:35] write interfaces and people can [48:37] understand how this all works. And I'm [48:40] like, "Wow, [48:42] is JavaScript really that busted?" And [48:45] and you're saying like the the way you [48:47] want to fix that problem is by [48:48] abandoning JavaScript, treating it as an [48:50] instruction language, right? And then [48:52] having a code generator target it. I'm [48:54] like, couldn't we like fix JavaScript? [48:57] Wouldn't that be better? Do you know [48:59] what I mean? And that's how Typescript [49:01] kind of got off the ground, right? It [49:03] was like, gosh, there's something here [49:05] that's really broken that needs to be [49:07] fixed, right? and when it comes to [49:10] JavaScript tooling [49:12] >> and that's what we set out to do. [49:14] >> You know, one thing I thought would be [49:16] interesting is in one of the talks that [49:18] you gave, you said that you believe that [49:21] the speed of your tooling is more [49:24] important now because of AI and I want [49:28] to hear thoughts on why is that the [49:30] case? Well, more and more our workflows [49:32] now are are dominated by agents that are [49:35] like running away in the background, [49:38] right? Right. I mean, like writing code [49:40] for you and they make mistakes just like [49:44] we do, but they but they but you know, [49:46] but you can have as many of them as you [49:47] want. So there are like many many more [49:49] little workers in the ecosystem writing [49:52] much more code, right? And that whole [49:55] workflow is like LLMs already have have [49:59] performance challenging is and then if [50:00] you add like if if you're writing code [50:02] in a big project and you have to like [50:04] type check it and takes two minutes [50:05] every time the LLM writes something. Do [50:07] you know what I mean? That's horrible, [50:09] right? So So making that go faster is is [50:13] a big benefit. [50:14] >> Yeah. Absolutely. I guess because it's [50:16] it's hammering away. [50:18] >> Yeah. Because I mean like like well we [50:21] all know LLMs they they like to use GP [50:24] and and whatever right but then they're [50:26] also smart enough now to realize that if [50:28] you're like trying to change this [50:30] property called version and like every [50:33] other object has a version property. You [50:36] can't just grip for version and then go [50:38] rename it to something else because like [50:40] you're breaking all these other [50:42] interfaces that have a version in them, [50:44] right? So you got to do semantic search [50:46] and the only thing that can do semantic [50:48] search is a compiler and so you got to [50:52] use the compiler through typically [50:54] through LSP through language services or [50:57] through our our command line tool that [50:59] would give you the equivalent right and [51:01] so more and more AI is doing that um and [51:06] that means you know compilers run at you [51:09] don't you may not even see that they're [51:11] running but they're running [51:13] and they're doing work on on your [51:14] behalf. Yeah. [51:16] >> When you talk about AI, it's very [51:20] realistic and grounded in the software [51:22] engineering. And so I thought it might [51:24] be interesting to uh run some common AI [51:28] takes that I hear from the internet and [51:31] you get your sense of how accurate is [51:33] this? What are your thoughts on when or [51:35] if it'll be true? Okay. Okay. So the [51:38] first one that I've heard um this is [51:40] more common at the end of last year is [51:42] that you know AI is going to write 90 [51:45] plus% of the code you know within a [51:47] year. Um curious what you think on that. [51:51] >> Well for certain classes of apps that [51:54] that might like all divide code coded [51:56] apps they're writing 100% of the code [51:58] right and and there's an awful lot of [51:59] that being written. [52:01] Are they going to write 90% of the high [52:03] quality code on the internet? I don't [52:05] know about that. Um so the the thing is [52:09] like 90% of what the volume of written [52:12] code is just like going like that right [52:15] now right because AI writes so much code [52:18] so [laughter] [52:19] so in a sense that's a self-fulfilling [52:21] prophecy right I mean but [snorts] but [52:24] but when it comes to like [52:27] the super high quality code that no one [52:29] has ever written before um it's not [52:32] clear to me that AI is going to write [52:34] 90% of that. So when you think about [52:36] cases that AI is not writing all the [52:40] code, maybe some examples of the super [52:42] high quality stuff, what is that? [52:44] >> Well, [52:46] I mean it's it's algorithms that no one [52:48] has ever seen before, for example, or or [52:50] particular solutions like I mean I I [52:52] know that AI could not write our [52:55] compiler, the TypeScript compiler. It it [52:57] just can't. I mean we've tried it. It it [53:00] can't do it. Um and I'm not asking it to [53:03] either. I mean, I'm not expecting it to [53:05] either. Um, but but our compiler is also [53:10] not a typical piece of code. I mean, [53:12] that's why it's bad at writing it [53:14] because it's seen none of it in the [53:16] training set. Well, I've seen some [53:17] compilers, but not like this one. Not [53:19] with these concepts, not with done the [53:21] way that that we're doing it, right? And [53:23] so, it's just not a good fit there. AI [53:26] we we we can't forget that AI is at [53:30] heart a big stochastic machine that has [53:33] memorized the entire internet, right? [53:35] And and is ability and has an ability to [53:37] extrapolate somewhat over what it's [53:40] memorized, right? Um but if it hasn't [53:43] seen it before, it's it's it's not [53:45] necessarily going to be all that good at [53:47] at doing it. Um it's getting better. I [53:50] mean, I'm not saying it's it's not [53:51] impressive. I it's it's wildly [53:53] impressive what it can do, but I just [53:57] think there's a long way still to it's [54:00] doing all of it. [54:02] >> And I don't know that we ever get there. [54:04] I hope we don't because then what's the [54:06] point of humans anymore then? I mean, [54:08] it's [laughter] [54:09] >> Well, I see this take often, too, is um [54:12] you know, you won't need to use an IDE [54:15] within the year or you don't need to [54:17] read the code anymore. [54:19] >> Well, good luck to you. I mean, if [54:21] you're going to hand AI the keys, [54:24] I mean, then all bets are off, right? I [54:26] mean, the minute AI you can't convince [54:28] AI to fix this issue or this new feature [54:31] that you want built, what are you going [54:32] to do? I mean, if you don't understand [54:36] what what's below, right, that's one [54:39] problem. The other problem is, let's say [54:41] a user comes to you and goes, your app [54:43] just stole my bank account. I'm well, [54:47] it's going to sue you. It's not. They're [54:48] going to sue you, not the AI. I mean, [54:50] it's like at the end of the day, someone [54:52] has to take responsibility for what AI [54:55] is doing. And if you're giving it the [54:57] keys, well, it's on you, you know, but [55:00] but I don't know. I personally would not [55:05] feel comfortable. I wouldn't be able to [55:06] go to sleep at night. I mean, if I [55:09] didn't understand what it is that I am [55:11] vouching for. [55:13] Why is there such a big difference [55:14] between this opinion and what I see from [55:20] maybe people who work at Anthropic? [55:22] >> Well, the difference is all I'm saying [55:25] here is not that AI can't do amazing [55:27] things. It does it can it does that [55:30] every day. But but people love these [55:34] like take it all the way to 100%. Right? [55:36] And that's where I get off the bus a [55:39] little bit, right? I think, oh yeah, [55:40] okay, fine. We can get we can get higher [55:42] and higher percentage but there still [55:45] has to be someone understanding what's [55:48] going on and how it's relevant to our [55:50] business problem and how it relates to [55:52] what our organization is doing and like [55:54] I mean there's so many other things that [55:55] have to be connected that it's I think [55:57] it's wrong to just view it as AI did it [56:00] all and we were completely unnecessary [56:02] you know and [56:04] >> yeah the next one I was going to ask you [56:06] was you know three years from now will [56:08] AI replace junior software engineers or [56:11] what junior software engineers do today. [56:13] >> Well, if it does, then how do you ever [56:15] get senior software engineers, [56:18] >> right? I mean, it's it's like I don't [56:20] think so. Well, I not unless you also [56:22] believe that you will be able to do your [56:24] business three years later than that [56:27] without any senior software engineers, [56:30] >> right? [56:30] >> Because where are they going to come [56:31] from? You got to train them. I mean and [56:35] but to me I think maybe one thing that [56:39] to some extent has happened is that for [56:41] certain classes of programmers the the [56:43] the pyramid has narrowed at the bottom [56:45] right there are fewer people coming in [56:48] um and we are wanting them to advance [56:51] higher up faster um so that they can get [56:55] to this more supervisory role right I [56:58] think the the craft of being a software [57:01] engineer is definitely changing from [57:03] you're you're typing in lines of code to [57:08] you're having agents type in lines of [57:10] code and you are reviewing the work of [57:12] the agents, right? And so so you do more [57:16] reviewing, less typing. [57:18] Um, and some people love that, you know, [57:21] I mean, and and and and really are [57:23] fantastic at at that workflow, right? [57:26] But it's it's a change in nature of of [57:28] what what the job looks like as a [57:30] programmer. And this tool that you now [57:32] have in a toolbox is having that impact, [57:35] right? But it is but a tool and there [57:38] are still programmers involved in the in [57:40] the process that I firmly believe. [57:43] >> It sounds like you enjoy typing out the [57:45] code. Would you be less happy if five [57:48] years from now [57:49] >> I I I for for 40 50 years I have enjoyed [57:52] typing out code. Um [57:55] I'm actually there there some and so I [57:59] will continue to type certain parts of [58:01] the code, you know, but there are other [58:02] parts of the code that I don't [58:04] particularly care to type. I don't care [58:05] to type in tests and follow all the [58:08] rigor of the particular testing [58:10] framework. Heck no. If I can farm that [58:12] out to AI, happy me, you know. Um I do [58:16] think reviewing has always been harder [58:18] for me. It's harder for me to like spend [58:20] time on reviewing other people's code [58:22] than it is you know writing the code. [58:24] But I also think that over time we will [58:27] we can make that process of reviewing [58:29] code much more ergonomic than it is [58:32] today. Right? I mean often today you [58:34] just get here's like the list of the [58:35] files that were changed and here are the [58:37] deltas. You figure it up, right? I mean [58:40] AI could help us more there by [58:41] explaining what the changes are and and [58:43] whatever. And so I I think we're going [58:45] to get better at this. It's going to get [58:46] more interesting, but it will change the [58:49] nature of of the craft. [58:53] You said that you've been writing code [58:55] for 40 maybe 50 years. [58:58] >> What is the hardest piece of code you've [59:01] ever written or what's the most [59:02] technically challenging thing you've [59:04] ever done? [59:05] >> There there are so many things that in [59:08] their time were challenging, you know. [59:10] Um [59:13] I mean this last project we worked on, [59:15] we knew that like like you know sort of [59:18] the easy part was getting the native [59:20] code. it's just like just just move it [59:22] to this other language, right? But then [59:25] this taming this beast called uh shared [59:29] memory concurrency and and getting the [59:33] compiler to use like as many CPUs as [59:36] there are available on your box, right? [59:40] That is not a simple problem to solve in [59:42] a in a in a compiler because we're all [59:45] taught to write sequential stuff, right? [59:48] I mean first you do this then you do [59:49] this but how do you do all of this at [59:51] the same time and then share the data [59:53] structures afterwards without anyone [59:55] like accidentally modifying the other [59:57] guy's data structure and you know how do [59:59] [snorts] you in the cases where you have [60:00] to do that how do you then synchronize [60:02] it and avoid deadlocks and race [60:03] conditions and and and whatever right [60:05] this it was it was tricky uh there were [60:08] some good technical problems uh that [60:10] that we licked that I think we can be [60:12] proud of you know but [60:14] >> what about when hardware was more [60:16] constrained earlier in your career Is [60:18] there any wacky thing you had to do to [60:21] kind of, you know, make it work? [60:23] >> Oh, totally. I mean, when I started it [60:26] was a like being a programmer was a very [60:28] very different thing, right? I mean, I [60:30] started out with with 8-bit micros that [60:32] had Microsoft basic in ROM, right? And [60:35] and the basic interpreter and and you [60:38] could buy these books and type in these [60:41] Star Wars games or or or whatever. They [60:43] were all text, you know, there was just [60:45] scrolling and and telling you there's [60:46] Klingons over in that C quadrant, you [60:48] know, and K4, you know, you got to [60:51] whatever, right? Um, [60:55] but I got fascinated with understanding [60:58] how it was all put together and and got [61:00] and and quickly learned how to write uh [61:03] assembly code and Turbo Pascal, the [61:06] first product I worked on, was all [61:08] written in Z80 assembly code. um the [61:11] compiler, the editor, the runtime [61:12] library, everything was assembly. Um and [61:16] writing structured a compiler in [61:18] assembly code is like that that was that [61:21] was like took a lot of fiddling, you [61:24] know, and I mean and you were counting [61:26] like okay, I think I can I need to we [61:28] need to squeeze this into this EPROM and [61:30] then there's only 12K, you know, and I'm [61:33] I'm 20 bytes over budget here. Oh, but I [61:36] can make this jump this long jump [61:38] instead. I could jump to this short jump [61:40] and that then jumps to that jump and [61:42] then I could save one and that's one [61:44] bite saved. Okay. You know, moving right [61:46] along. [laughter] I mean, and you you [61:48] would you would you you were just like [61:49] sitting there and fiddling, you know, it [61:51] was it was a craft. It was like [61:53] woodworking almost. I mean, it was just [61:55] so different from what we do now, right? [61:57] Everything is like it's bottomless pits [62:00] of capacity and and and and bottomless [62:02] pits of expectation from users, right? [62:05] Is there a top technical book [62:07] recommendation you have for software [62:09] engineers? I usually recommend the same [62:10] but the the one book that was like the [62:13] it book for me when I was younger and [62:15] it's called algorithms plus data [62:17] structures equals programs by Nicholas V [62:20] uh the inventor of Pascal and then later [62:23] modular and Oberon and whatever and it's [62:26] a [62:27] it's a book that is [62:30] light on [62:32] math and symbolism uh and rich in [62:36] instructive examples and good [62:38] explanation. ations about how data [62:40] structures work. I mean, that's how I [62:42] learned about hashts, right? I mean, [62:44] like when you're self-taught, you don't [62:46] know about hashts. You sort of know [62:48] about linked lists, right? And fine. So, [62:50] in the original version of Turop Pascal, [62:53] all the symbol tables were just well, [62:55] they were just linked lists, you know, [62:57] or whatever. And then of course as you [62:58] had many local variables well you're [63:02] you're you're you're going exponential [63:04] in search time to you know and then I [63:07] read about these hash tables and like [63:08] wow what you mean I can like just do [63:11] this and then like it's it's basically [63:13] like linear lookup time and implemented [63:17] and the compilement twice as fast right [63:19] I'm like holy cow [laughter] [63:22] you know that was useful reading do do [63:24] you know what I mean so I was always [63:25] like the engineer it like that that I [63:29] mean and and understanding how to do [63:31] error recovery. He explains that in like [63:33] how you construct a simple compiler and [63:35] then like you know and it's it's [63:38] a it was for me a great book but and now [63:41] it's actually like I mean it's just a [63:43] big PDF you can download it out there um [63:46] it's out of print since 40 30 years. [63:49] Yeah. Last question for you is with all [63:52] the experience that you have now, if you [63:54] could go back to yourself when you just [63:56] entered the industry and give yourself [63:57] some advice, what would you say? [64:01] >> Well, I a couple of things maybe like we [64:04] talked about being a team player, you [64:05] know, I I I would have probably tried to [64:07] educate myself a bit more about that to [64:09] to begin with. Um, I think also [64:14] one thing in in retrospect is like [64:18] don't let people tell you that it can't [64:20] be done. When they tell you it can't be [64:23] done, it's because they can't do it. [64:25] That doesn't mean that you couldn't [64:27] possibly do it. Do do you know what I [64:29] mean? So, so don't let that discourage [64:31] you. Is there a project where you [64:34] someone said you couldn't do it and then [64:36] you did it and that's how you [64:38] >> Well, I think the first thing I worked [64:39] on like Turbo Pascal, people were [64:41] telling me whenever we told them here's [64:43] what we have, they said that can't be [64:45] done. That's like nah, you guys are you [64:48] full of That's like not possible, [64:50] you know. [laughter] [64:51] Well, it was. And I didn't know that it [64:54] wasn't possible, right? [64:56] >> Awesome. Well, thank you for your time. [64:57] I really appreciate it, Andrew. [64:58] >> You're welcome. No, this is a lot of [64:59] fun. Hey, thank you for watching this [65:01] podcast. If you liked it and you want to [65:03] see the show grow, please support with a [65:05] comment or a like. Also, if you have any [65:08] recommendations for people you want me [65:10] to bring on, please drop a comment. [65:13] Guests like Barbara Liskoff, Mike [65:15] Stonereaker, Mark Brooker, these were [65:17] all people that I brought on because [65:19] someone left a comment. On another note, [65:21] aside from the podcast, I'm working on [65:23] building the ergonomic keyboard that I [65:25] wish existed. Here's a glance at the [65:27] prototype. It's a split keyboard, so [65:30] there's two sides. This is in the case, [65:32] but yeah, we launched on Kickstarter and [65:34] we hit our goal within eight hours of [65:36] launching. I really appreciate it if you [65:38] were one of the people who grabbed one [65:39] of the early units. Um, we're now [65:41] working on the long journey of building [65:43] the tooling now. And so, if you still [65:45] want to pick one up, I've left the late [65:47] pledges open on Kickstarter, so you can [65:49] grab one there. I'll put a link in the [65:51] description. Thank you again for [65:53] watching the podcast and I'll see you in [65:56] the next