The notion of progress in programming is -- as in anything else -- debatable and hard to define. For various reasons that are besides the point of this essay I believe that we're indeed making progress in the art of programming (otherwise what's the point in getting up in the morning afternoon and going to the office?).

But how does progress happen in programming? Sometimes it looks like it's an arbitrary walk in the space of possible languages, frameworks and architectures. I'd like to propose an answer: programming progresses in dialectical fashion. Meaning what usually follows the current best practices and technologies is an opposite in many ways. However, this is usually followed by a synthesis of these two opposites. In other words, a compromise or a best of both worlds.

We can think of this as a thesis, antithesis, synthesis:

(1) a beginning proposition called a thesis, (2) a negation of that thesis called the antithesis, and (3) a synthesis whereby the two conflicting ideas are reconciled to form a new proposition.

Let's look at some examples.

Languages: industrial strength vs developer friendliness

  1. Thesis: industrial strength programming languages. Languages like Java and C++ are type-safe, efficient and work well with large systems. But they're also hard, boring, noisy, and take a long time to compile.

  2. Antithesis: developer friendly languages. Languages like JavaScript, Python, and Ruby are dynamically typed so the syntax is clean and less noisy. They're interpreted so there is no compiler to wait for. And they're fun and arguably more productive to work with.

  3. Synthesis: developer friendly and suitable for large scale programming. Languages like Go, Rust, and TypeScript are both type-safe, efficient and work well at large scales.

Web rendering: server-rendered vs client-rendered pages

  1. Thesis: server-rendered pages. Languages and frameworks powering Web 2.0 like PHP and Ruby on Rails can get you to market quickly, with predictable performance, and works well with the rest of the web infrastructure (links, search engines etc).

  2. Antithesis: client-side rendered pages. Frameworks like Backbone, React, and Angular can create delightful user experiences. But they break the web's protocol (hypertext over TCP) and can be slow to boot up.

  3. Synthesis: universal rendering. Frameworks like Next.js bring us the best of both worlds: a great user experience, great initial render time, and great support for search engines and other web infrastructure.

Mobile apps: native vs web

  1. Thesis: web applications. Web 2.0 unleashed the power of the internet and brought us amazing applications like social networking and YouTube. But when mobile came around, using web tech to build mobile apps created monstrosities like the first Facebook HTML5 app.

  2. Antithesis: native applications. Native applications brought much better user-experience with gesture support, smooth scrolling, and access to APIs like location and notifications. However, a lot of progress that we made in engineering (e.g. continuous deployment, cross-platform development) or in application distribution (just visit a URL) had to be thrown away.

  3. Synthesis: progressive web apps and web tech adapted to native. PWAs and frameworks like React Native bring us the best of both worlds. Access to native (or native-like) APIs and a great user experience but also cross-platform development, continues deployment and better application distribution strategies.

Conclusion

This framework of thinking about progress in programming seems to apply to a lot of what I see happening in programming. There are ongoing developments that I look forward to seeing the synthesis of:

There are a lot more industry trends that can be described and understood using the dialectical framework of progress. I'd be curious to hear your thoughts on this and if you think if this framework applies to trends in your programming community. I'm best reachable on twitter. Thanks for reading.