The Architect of Modern Programming: A Conversation with Anders Hejlsberg
Anders Hejlsberg, a titan in the world of programming languages, has shaped the development landscape for decades. From the lightning-fast Turbo Pascal to the ubiquitous C# and the game-changing TypeScript, his influence is undeniable. In a recent conversation, Hejlsberg shared insights into the creation of these foundational tools, the evolution of software development, and the burgeoning impact of AI.
From Humble Beginnings to Turbo Pascal
Hejlsberg's journey into programming began in a Danish high school in the mid-1970s, where he gained access to an HP 2100 computer. This early exposure to hardware, with its visible core memory and paper tape reader, offered a rare glimpse into the fundamental workings of computing. He recalls programming in Fortran and a peculiar version of Algol that lacked recursion, forcing careful algorithm design. His early programming endeavors often involved building games like lunar landers, a common pursuit for young enthusiasts of the era.
His formal education at the Danish Technical University in 1979 coincided with the rise of 8-bit microprocessors. He built his own Z80-based kit computer, the Nascom, and learned assembly programming. This hands-on experience led him and college buddies to found Copenhagen's first computer store, selling early microcomputers and later Apple IIs and Commodore 64s. While these machines came with Microsoft's ROM Basic, Hejlsberg yearned for a more robust programming language. Discovering Pascal, he found it simpler than Algol and embarked on creating his first compiler—a small, 12KB ROM-based implementation that allowed users to run Pascal programs on their machines. This early work served as a precursor to Turbo Pascal.
In 1989, Hejlsberg joined Borland, which had a royalty agreement with his previous company. This collaboration led to the release of Turbo Pascal in 1983. The language's name, "Turbo," was a direct nod to the era's fascination with speed, exemplified by Audi's turbocharged cars. Turbo Pascal was not just fast; it was also highly interactive, offering a seamless editing, compiling, and debugging experience that was revolutionary for its time. This integrated development environment (IDE) approach, focusing on the entire development cycle, was a key factor in its widespread adoption.
"Turbo Pascal was always about building that whole cycle and try to make it as interactive as basic was as an interpreted language, right? But giving you the performance of a compiled language and the better, you know, semantics and syntax of Pascal versus Basic," Hejlsberg explained.
The Evolution to Delphi and C#
The advent of graphical user interfaces (GUIs) and the rise of Windows presented new challenges and opportunities. Borland's next major product, Delphi, emerged as a powerful IDE for Windows development. It aimed to compete with Microsoft's Visual Basic by offering a compiled, object-oriented approach for rapid application development, particularly for client-server and enterprise applications. The success of Delphi was evident even years later, with Hejlsberg noting that the Skype application, acquired by Microsoft, was built using Delphi.
Hejlsberg's career took a significant turn in 1996 when he joined Microsoft. The mid-90s were dominated by the buzz around Java, which promised platform independence and applets that could run anywhere. Microsoft's initial response was Visual J++, an attempt to bring Java development to Windows. Hejlsberg was brought in to architect Microsoft's Java development tools, but the landscape shifted dramatically with the Sun Microsystems versus Microsoft lawsuit over Java. This legal battle effectively sidelined Visual J++ and prompted a strategic re-evaluation.
Microsoft's development landscape at the time was bifurcated: Visual Basic offered ease of use and rapid development, while C++ provided power and expressiveness but with a steeper learning curve. Developers craved a language that combined the best of both worlds, along with modern features like garbage collection and exception handling. This need, coupled with the desire to create a platform-independent runtime (.NET) and a competitive language against Java, laid the groundwork for the creation of C#.
Designing C#: A Unified Vision
The design goals for C# were ambitious: an object-oriented language with managed code (bytecode) for cross-runtime compatibility, garbage collection, and exception handling. A key focus was a unified object system, enabling features like reflection and dynamic manipulation of objects. Properties, methods, and events were made first-class citizens, reflecting the component-based nature of modern software development.
"We knew we wanted to build an object-oriented language. We wanted manage code or bite code so we could target different runtime environments. We wanted garbage collection and exception handling, but also things like a unified object system," Hejlsberg recalled.
The C# design process itself was a testament to focused collaboration. A small team of six to seven experienced language designers convened regularly, rigorously critiquing each other's ideas. This lean, iterative approach, where only the strongest concepts survived, was crucial to the language's robust foundation.
The Async/Await Revolution
C# also introduced significant innovations, notably the async/await pattern. This feature addressed the complexities of asynchronous programming, particularly in event-driven environments like JavaScript and Windows. Traditional approaches often involved intricate state machines and callback hell, making code difficult to write and maintain.
async/await transformed this by allowing developers to write asynchronous code that reads like sequential code. The compiler handles the underlying state machine transformation, abstracting away the complexity. "Await is basically I'm saying I want to yield here and then when the promise completes I want you to come back here and continue executing and then the compiler writes a state machine around it," Hejlsberg explained. This elegant solution proved so effective that it has been adopted by numerous other languages, including JavaScript, Python, and Rust.
The Rise of TypeScript and the Power of Types
As JavaScript's popularity surged, driven by browser advancements and the mobile revolution, its limitations became increasingly apparent. The lack of a type system hindered the development of large-scale applications and robust tooling. Hejlsberg observed this trend and, rather than creating another language that compiled to JavaScript, proposed fixing JavaScript itself by adding an erasable type system.
This idea led to the creation of TypeScript. The core principle was to leverage types to enable superior developer tooling—autocompletion, refactoring, and error detection—without altering the runtime behavior of JavaScript. "We were totally right there that adding an erasable type system and then using that to enable great tooling is where the productivity boost is realized," he stated.
The decision to open-source TypeScript was critical. In an era when Microsoft was still perceived as anti-open source, this move was surprising but necessary for adoption within the JavaScript ecosystem. The initial move to Microsoft's Codeplex repository yielded little traction, but the subsequent migration to GitHub in 2014 marked a turning point, leading to its explosive growth and eventual status as the most popular language on the platform.
The TypeScript compiler itself is a marvel of engineering, designed for highly interactive use within IDEs. It employs lazy evaluation and deferred computation to provide near-instantaneous feedback, even on massive codebases. This approach, which differs from traditional compilers, prioritizes responsiveness and a seamless developer experience.
AI and the Future of Programming
The conversation naturally turned to the impact of Artificial Intelligence on software development. Hejlsberg acknowledged that AI tools are becoming increasingly capable, assisting with code reviews, issue fixing, and even generating tests. However, he emphasized that AI is currently a tool to augment, not replace, human programmers.
"We're not at a point where it absolves us from understanding what we're doing. Not at all," he asserted.
He highlighted the importance of languages that are well-suited for AI, pointing to TypeScript's combination of explicit types and type inference as a key advantage. Types help guide AI when context is lacking, while inference allows for more concise and efficient code generation, aligning with AI's need for fewer tokens.
Looking ahead, Hejlsberg believes that as AI generates more code, language features that promote locality and reduce the reliance on global state will become increasingly important. This will help manage the complexity of large codebases and improve the efficiency of AI's context window.
The Enduring Craft of Software Engineering
Reflecting on his decades-long career, Hejlsberg identified productivity as the ultimate goal for developers. He stressed that designing a programming language is not just about syntax and semantics but about creating an entire experience that allows programmers to enter "the zone." This holistic view, encompassing the IDE and the entire development cycle, has been a guiding principle throughout his work.
The rise of AI agents is shifting the focus of software engineering. Hejlsberg suggested that the craft may evolve from writing code to reviewing and architecting it, managing an "army of junior programmers" in the form of AI agents. However, he cautioned against the notion that AI will eliminate programmers entirely. The responsibility for code, the ability to reason about complex systems, and the need for deterministic behavior remain firmly in the human domain.
"Ultimately, AI is a tool to enable us to become more productive, I think, but it will change the way that we write our programs for sure," he concluded.
For those looking to deepen their understanding of fundamental programming concepts, Hejlsberg recommended "Programs + Data Structures = Algorithms" by Nick Vit, a book that continues to offer timeless insights into the core principles of computer science.
Key Takeaways
- The Integrated Experience: The success of languages like Turbo Pascal and TypeScript stems from a focus on the entire developer experience, not just the compiler. This includes editing, debugging, and runtime environments.
- Evolution Driven by Need: Programming languages evolve to meet new demands, from the speed of Turbo Pascal to the GUI capabilities of Delphi and the type safety required for large-scale JavaScript applications with TypeScript.
- Collaboration is Key: Small, experienced teams can achieve remarkable results, as demonstrated by the lean design process for C#.
- Types Enable Tooling: Adding an erasable type system, as with TypeScript, is crucial for building powerful developer tools and improving productivity.
- AI as a Tool, Not a Replacement: AI is a powerful assistant for programmers, but human understanding, architectural oversight, and responsibility remain paramount.
- Long-Term Vision: Developing impactful programming languages is a long game, often requiring a decade or more to reach maturity and widespread adoption.