Grep is indeed a critical tool for navigating and understanding an unfamiliar codebase, but greppability should not be a goal unto itself. The article seems to be making that mistake - it's basically advocating improving greppability at the cost of making the codebase even larger, messier, and harder to read: i.e. reinforcing the problem that makes you reach for grep in the first place. It's a false economy. It's asking you to optimize your code for one specific scenario - trying to figure out where an unfamiliar string comes from; but that isn't the most important or most frequent thing people need to do with code anyway.

(If it is for you, congratulations, you're the janitor in the codebase. It sucks, but that's what you're being paid for. Maintenance is a means, not an end.)

In particular, one of the most important and frequent thing you do with code is read it in order to understand it (locally, at the abstraction level of interest), and the advice from this article compromise it badly - almost as if hoping that, on a greppable enough codebase, you could use grep to avoid reading or thinking entirely.

1. Don't split up identifiers

Don't split them up for the sake of splitting, sure. That's not helping anything. But in the example given, there's likely a good reason for it - for example, it codifies the intended coupling between tables. `billing_address` isn't an independent term in this code, nor are the other `_address` table names. There's a naming pattern there, encoded directly in the initial example. The proposed refactor obscures it and triples the amount of code in the process (all of which is low-value noise) and introduces possibility of making errors (typos, copy-paste) of the kind that isn't picked up by compilers (hope you have good tests!).

FWIW, the author's refactor may be eventually required - if and when the naming pattern in the original code no longer holds. But not before then.

2. Use the same names for things across the stack

Excessive data repackaging is bad, but that tends to be a symptom of having too many layers. A good layer has specific semantics that distinguish it from layers above and below it. This may necessitate renaming some thing, in which case even if such renaming is as trivial as in the example, it should be spelled out explicitly; you can't just return Layer 1 Address object instead of Layer 3 Address object, if the two layers mean something different by "Address"; the triviality of the mapping is incidental and may not hold over time. If it really feels trivial, chances are one of the layers is not necessary in the first place, so go fix that.

3. Flat is better than nested

Now that's just screwing with people, especially wrt. nesting namespaces. It's asking to reintroduce the visual noise that the person reading the code will then have to filter out again mentally.

The way I see it, if you grep for some log message or unrolled identifier and can't find it, you're supposed to keep grepping for parts of the string, until you hit a match. You then go look, and it's usually apparent that you're dealing with a compound identifier or an interpolated string - congratulations, you just learned something important about that part of the legacy codebase, which is the real job you're supposed to be doing.