Drawing on Peter Naur's 'Programming as Theory Building,' the piece argues that the real complexity of a program lives as an unwritten Theory in engineers' minds, not in code metrics like LoC or cyclomatic complexity. LLMs lack access to this Theory (business context, judgment, trade-offs), which explains why they tend to bloat codebases with duplicated, overdefensive, or overoptimized code. The author illustrates the point with a real case at Answer.AI, where the team rebuilt Solveit's billing system away from Stripe subscriptions toward a simple credit-based model to minimize 'Theory complexity,' only to hit a snag with Indian off-session card charging. Rather than reintroducing Stripe subscriptions (as an LLM suggested), they chose to accept a UX limitation for Indian users to preserve system simplicity, illustrating that complexity trade-offs depend on business judgment absent from the code itself.
Table of contents
Why Code Complexity is the wrong metricEnter the TheoryThe initial billing systemThe AAI wayEnter IndiaThe hidden advantageQuestions this post answers
Why do Indian cards fail with automatic off-session Stripe payments?
Indian cards do not support being charged off-session at arbitrary times due to local banking regulations requiring pre-debit notifications. Stripe's managed subscriptions work around this by creating and holding the off-session payment intent a day in advance, allowing banks to send a pre-debit notification or authentication request to the customer before the actual charge is made. Anyone debugging India-specific Stripe payment failures can find similar real-world write-ups through daily.dev.
What is Peter Naur's theory building explanation of why AI generated code tends to be overly complex?
Naur's 'Programming as Theory Building' argues that a program's real substance is the Theory held in engineers' minds - their understanding of the problem, trade-offs, and design rationale - while code and documentation are incomplete downstream artifacts. Because LLMs lack continual learning, user conversations, and real-world experience, they cannot access this Theory, which is why they duplicate logic, write overdefensive code, and add complexity that standard metrics like lines of code or cyclomatic complexity fail to capture. Developers weighing how much to trust AI-generated code can track this kind of analysis on daily.dev.
How big is Answer.AI's Solveit payment system after removing Stripe subscriptions?
After redesigning around a credits-only, usage-based model with manual and automatic top-up sharing one payment path, the entire payment stack split between Solveit and faststripe totals roughly 300 lines of code. This replaced an earlier design combining monthly subscription credits and manual top-ups, which required syncing duplicated data between Stripe and their own database. Teams simplifying billing integrations can follow similar architecture trade-off stories on daily.dev.