20+ Years in Tech: Things We Wish We Knew Sooner • Daniel Terhorst-North & Kevlin Henney

In a reflective and forward-looking conversation, Daniel Terhorst-North and Kevlin Henney explore the evolution of software development over the past 20 years and predict the key challenges and innovations for the next 20. They delve into the philosophy of programming language design, the critical need for hardware-sympathetic programming, the untapped potential of concurrency models like CSP and the Actor Model, and the future of user interfaces and decentralized technology.

5 min read
20+ Years in Tech: Things We Wish We Knew Sooner • Daniel Terhorst-North & Kevlin Henney
source: https://www.youtube.com/watch?v=aiyS2CdI4GM

Daniel Terhorst-North and Kevlin Henney reflect on the evolution of software development since they first met at the JAOO conference in 2004, projecting forward to what the industry might look like in 2044.

On BDD and Letting Ideas Grow

Daniel North recounts his deliberate choice not to write a definitive book on Behavior-Driven Development (BDD). He felt that Gojko Adzic’s book, Bridging the Communication Gap, perfectly captured the essence of BDD. Inspired by Kent Beck’s approach with Extreme Programming (XP), North chose not to monetize or tightly control the IP of BDD. Instead, he put the ideas out into the world to be shared, adapted, and grown by the community. This philosophy, he notes, allowed brilliant minds like Liz Keogh, Chris Matts, and the creators of Cucumber to take the concepts in directions he never would have imagined. North shares a piece of advice that shaped this thinking: “If you want an idea to go a long way, don’t try and go with it.”

The Philosophy of Programming Languages

A discussion on language evolution highlights differing perspectives. While it’s often said that new languages absorb the features of their predecessors, North argues that modern languages are often a strong expression of a particular design position.

  • Opinionated Design: Languages like Rust, with its opinionated borrow checker and type system, or Go, with its deliberate simplicity, don’t try to include everything. Go, described as “a language so ugly the only thing you can do with it is work,” intentionally omits features like list comprehensions in favor of simple for loops.
  • The Case of Go: Go was designed at Google to solve a specific problem: the complexity and slow build times of their enormous C++ (Search) and Java (Ads) codebases. The goal was a deliberately small language with a fast toolchain and a gentle on-ramp for C++, Java, and Python programmers. Its initial lack of generics was a conscious decision to maintain compilation speed, a core design principle. The eventual addition of generics was seen as an inevitable outcome for any popular, statically-typed language.
  • Lifecycle of Languages: Languages evolve. A language’s version one is often the pure, opinionated vision of its creators. Over time, as design teams change and user demands grow, languages tend to accumulate features, sometimes leading to a “bag of language features,” as humorously noted in the case of Scala.

The Next 20 Years: Programming for Modern Hardware

A central theme for the future is the urgent need for software to become more sympathetic to the hardware it runs on. Current programming paradigms are incredibly wasteful of the computational power available in modern systems-on-a-chip (SoCs).

The Resurgence of High-Abstraction and Vector Languages

Languages like APL and K are predicted to see a resurgence. By expressing complex operations like matrix inversion as a single command, these vector languages give the compiler and runtime enormous freedom to parallelize and optimize execution for modern vector registers and multi-core architectures. This allows programmers to work at an appropriate level of abstraction for the problem, letting the system handle the low-level optimization.

Concurrency Models for a Multi-Core World

The future lies in models that embrace concurrency and locality, concepts that have existed for decades but have yet to be fully adopted.

  • Communicating Sequential Processes (CSP): Go’s concurrency model, based on Tony Hoare’s CSP, is highlighted. It uses lightweight goroutines (processes) that communicate via typed channels. This approach encourages structuring programs as a network of small, independent agents passing messages, which maps beautifully to the architecture of modern chips where memory and compute are tightly co-located. This minimizes performance penalties like cache misses.
  • The Actor Model and Erlang: The Actor Model, conceived 50 years ago, is exemplified by the Erlang programming language. The key is not just the language but its runtime, OTP, which is arguably the most observable and robust runtime system ever created. The famous example of the Copenhagen telephone exchange, which has run for decades with zero downtime despite numerous live updates to the underlying Erlang OS and application code, showcases its power. The speakers lament that the industry has failed to generalize and adopt these proven principles of building simple, unbreakable, and highly observable systems.

Future Tech, Power, and Society

Looking ahead, the conversation touches on broader technological trends:

  • Pervasive Computing: User interfaces will become more integrated, with technologies like contact lenses providing heads-up displays. This, however, brings the dystopian risk of pervasive, unavoidable advertising.
  • Decentralization and Locality: A major trend will be locality, not just in computing but in infrastructure. This includes data centers being designed to heat adjacent buildings and the rise of distributed power grids. Solar power in rural India and the rollout of 4G/5G networks in India by Jio (which leapfrogged traditional landline infrastructure) are cited as powerful examples of this shift away from centralized models.
  • Skepticism of Hype Cycles: The speakers express hope that the hype around power-hungry LLMs will subside, much like the cryptocurrency craze, as the industry confronts the economic and environmental costs.

Organizational Strategy: Managing Language Proliferation

In response to an audience question about the right number of languages for a company, the following balanced approach is recommended:

  1. Start Small and Opinionated: Begin with a small set of “blessed” languages rather than allowing a free-for-all. This improves internal mobility and reduces cognitive overhead.
  2. Establish Custodianship: Create a cross-functional group of people responsible for defining what “good” looks like for each blessed language. They set the house style and guide its evolution within the company.
  3. Have a Deliberate Onboarding Process: Introduce new languages gradually and strategically. For example, a Java shop might start using Kotlin for writing tests. This allows the team to gain experience and build a groundswell of support before the language is approved for production use, at which point it falls under the custodianship model.

Share post

Stay In The Loop! Subscribe to Our Newsletter.

Get updates straight to your inbox. No spam, just useful content.

Recommended for You

When Agents Hire Their Own Team: Inside Hypermode’s Concierge // Ryan Fox-Tyler

When Agents Hire Their Own Team: Inside Hypermode’s Concierge // Ryan Fox-Tyler

Ryan Fox-Tyler from Hypermode explains their philosophy of empowering AI agents to design and deploy other agents. He introduces Concierge, an agent that builds other agents, and details the underlying actor-based runtime built for scalability, fault tolerance, and efficient, event-driven execution of thousands of parallel agent instances.

The Hidden Bottlenecks Slowing Down AI Agents

The Hidden Bottlenecks Slowing Down AI Agents

Paul van der Boor and Bruce Martens from Prosus discuss the real bottlenecks in AI agent development, arguing that the primary challenges are not tools, but rather evaluation, data quality, and feedback loops. They detail their 'buy-first' philosophy, the practical reasons they often build in-house, and how new coding agents like Devon and Cursor are changing their development workflows.