Naive Implementation: The Art of Artless Programming
- 3 minutes read - 482 wordsA naive implementation is a programming technique that prioritizes imperfect shortcuts for the sake of speed, simplicity, or lack of knowledge.
Naive Implementation Example
What is ’naive’? Here’s the dictionary definition:
naive (adjective)
- marked by unaffected simplicity : ARTLESS, INGENUOUS –Merriam-Webster Dictionary
Let’s see it in a programming context!
A pangram is a sentence that contains all the letters of the alphabet, such as: “The quick brown fox jumps over the lazy dog.” Consider this problem I borrowed from Exercism, asking us to build a function that detects pangrams. We have written a failing test that describes our desired function.
class PangramTest < Minitest::Test
# Empty string is not a pangram
def test_empty_string
refute Pangram.pangram?('')
end
end
Naive implementations don’t have to be test-driven, but it does help make the
point. What would be a naive implementation of the pangram?
method? It would
take shortcuts. Here’s one:
class Pangram
def self.pangram?(_)
false
end
end
Looks silly! It doesn’t appear to detect pangrams at all, returning false
with
any argument. Why would we bother to write code like this?
Why We Would Bother to Write Code Like This
I don’t do this every time I code. But it’s a powerful technique for getting unstuck and shaking things up, for a few reasons.
First, this got us from zero to a working test, an unqualified victory. A lot
of code is not tested at all, if you can believe it! And, we aren’t solving the
problem of getting a test to run at the same time as we decide how pangram?
works. Our dumb green test here is what Adam Young would call “building from
success.” Let’s take that success and build from it!
Second, and stay with me here: pangram?
is not wrong… given what we
currently know. In a sense, it does detect pangram-ness, because the sentence
we’ve provided is not a pangram and it correctly identified that. We just
haven’t given it an actual pangram to consider.
Third, this technique ruthlessly exposes bad designs. Maybe we go through a
suite of assertions and find that we never had to improve upon this
implementation. This happens sometimes! We replace this function with a
hard-coded false
wherever it was intended to be called. Wouldn’t that be
nice? Our design was based on the assumption that people are going to need to
dynamically know if a sentence is a pangram, which was wrong.
Conclusion
Write a naive implementation, take the win, and earn your TDD stripes by proving that it isn’t good enough. Along the way, you’ll get a test that:
- Exists 💯
- Is correct until proven otherwise 🤷♂️
- Exposes bad designs 🔎
I learned this technique via Jim Weirich’s ‘Roman Numerals Kata’ live coding session at the Boston Ruby Meetup. It’s a masterclass. This video is hard to find online these days in an acceptable quality, so I thought I’d add my interpretation.