In a session at AI Engineer Europe, Matt Pocock, author of "It Ain't Broke: Why Software Fundamentals Matter More Than Ever," argued that despite the rapid advancements in artificial intelligence, the foundational principles of software engineering remain paramount. Pocock, also a teacher of "Claude Code for Real Engineers," emphasized that the allure of AI-generated code shouldn't overshadow the importance of robust design and maintainable codebases.
Pocock began by challenging the notion that AI represents a complete paradigm shift rendering old software rules obsolete. He described a common pitfall where developers, when using AI for coding, fall into a "specs to code" cycle that rapidly degrades into "garbage" code. This happens when the AI is not guided by a clear, shared understanding of the desired outcome.
The Pitfalls of AI Code Generation
Pocock outlined several failure modes he observed when developers rely too heavily on AI without proper guidance:
- The AI didn't do what I want: This failure stems from a lack of a clear, shared design concept. The AI, acting on vague instructions, produces results that deviate from the developer's intent.
- The AI is way too verbose: Often, AI models can be overly wordy in their explanations or code, creating a communication gap between the developer and the AI. Pocock stressed the need for a shared language, referencing Eric Evans' "Domain-Driven Design," where a common vocabulary ensures clarity.
- Code that doesn't work: This is a consequence of the previous issues. Without clear specifications and a well-structured codebase, AI-generated code is prone to errors. Pocock highlighted the importance of feedback loops, such as static types and automated tests, to catch these errors early.
- Doing way too much: AI can sometimes generate overly complex solutions when simpler ones would suffice. Pocock quoted "The Pragmatic Programmer" by David Thomas and Andrew Hunt, advocating for "small, deliberate steps" and recognizing that "the rate of feedback is your speed limit."
- AI doesn't understand my code: This occurs when the codebase is poorly structured, with shallow modules and complex interfaces. The AI struggles to navigate and comprehend such code, leading to ineffective output.
Deep Modules and Testability
Pocock advocated for "deep modules" in software design, drawing on John Ousterhout's concept. Deep modules, he explained, encapsulate a lot of functionality behind a simple interface, hiding complexity. This contrasts with shallow modules, which offer limited functionality and expose complexity through intricate interfaces.
"The best modules are deep," Pocock stated, quoting Ousterhout. "They allow a lot of functionality to be accessed through a simple interface." He further elaborated that deep modules hide complexity, making them easier to understand and test. This modularity is crucial for AI, as it allows the AI to interact with well-defined units of functionality without getting lost in the overall system's complexity.
The ability to test code effectively is a key differentiator. Pocock emphasized that "Good codebases are easy to test." He suggested that by focusing on deep modules with simple interfaces, developers create code that is not only easier to manage but also more amenable to AI-assisted development and testing.
The Power of a Shared Language
A significant portion of Pocock's talk centered on the importance of establishing a shared language, particularly when working with AI. He cited Eric Evans' "Domain-Driven Design" principle: "With a ubiquitous language, conversations among developers and expressions of the code are all derived from the same domain model."
Applying this to AI interactions, Pocock proposed using specific commands like `/grill-me` to prompt the AI for rigorous questioning and clarification, or `/write-a-prd` and `/write-issues` to guide the AI in generating product requirements and issue tracking. These commands essentially force the AI into a "plan mode," ensuring that the AI and the developer are aligned on the desired outcome before implementation begins.
Conclusion: Fundamentals Matter
Pocock concluded by reiterating that while AI is a powerful tool, it cannot replace the need for solid software engineering practices. He stressed that investing in good design and maintainable code is not a secondary concern but a fundamental requirement for successful AI-driven development. By embracing principles like modularity, testability, and clear communication, developers can better harness the power of AI to build effective and reliable software.
