A colleague at work pitched for a quick pair-programming session to spar on a problem he’d been dealing with without resolution. Happy to oblige, I huddled over to his desk.
The bug was seemingly obvious: the text input box’s caret flung to the wrong side of the box. But only when using right-to-left scripts. Our first guess is that a wrong index value is generated. Step-wising through the index calculation using a debugger only cemented our conflicting conviction that it “should be correct”.
But it was obviously broken. We took a deep sigh and pondered on next steps. While he was trying to make sense of the situation, I suggested to break it even more - hit it with a hammer! Create a conscious, judicial self-harm piece by piece - quick stabs in the dark testing interstitial bits and pieces. For example, make all text right-to-left, return a hardcoded caret x-position, or skip analyzing the layout with RTL altogether - things that you obviously shouldn’t do if you were to make a releasable product.
If you can’t make it right, make it wrong.
Half frowning, half surprised my colleague glanced at me: Why? To evaluate the correctness of made assumptions - to test our mental models, I answered - or I would have, had I figured that out on the spot, but I basically muttered “just try it” or something similarly unconvincing. But he humoured me and tried it out.
It turns out that returning values from a lookup table did not work as we reasoned out it would, which we found out by trying to break the system. This lead to fixing the actual problem in the end.
There is method to the madness here that is seemingly surprising to smart people that haven’t had a few years of engineering experience. I find it a bit surprising, because it’s about as naive of a method as ubiqutous log printing or commenting out code to verify effects.
Breaking the code is a valid and systematic method to take a step back, when it fits the case. Tweaking the details in new ways helps to learn the system better. Scope the task into smaller and faster pieces and evaluate interstitial results. And when you’re at a deadend, you have to try something. It’s like an inverse educated guess.