Jake Worth

Naive Implementation

Published: June 23, 2022 2 min read

In this post, I’d like to document a technique I’ve used over the years: a naive implementation.

A naive implementation takes imperfect shortcuts for the sake of speed, simplicity, or lack of knowledge.

Naive Implementation Example

Consider this problem: we need a pangram-detecting function. A pangram is a sentence that contains all the letters of the alphabet. “The quick brown fox jumps over the lazy dog” is a pangram.

We have a test that describes our desired function:

class PangramTest < Minitest::Test
  def test_sentence_empty
    refute Pangram.pangram?('')
  end

A naive implementation of this function would be imperfect, taking lazy shortcuts. Here’s one:

class Pangram
  def self.pangram?(_)
    false
  end
end

Looks silly! It doesn’t detect pangrams at all! It just returns false for any argument. Why would we write code like this?

When It’s Useful

I don’t do this every time I code. But it’s a powerful technique for shaking things up, for a few reasons.

First, this got us from zero to a working test harness, and that is a standalone victory. Many times I’ve spent ten minutes wrestling with a failing test, to find out it was set up incorrectly. We’ve moved past that problem in a couple of keystrokes.

Second, and stay with me here: it’s not wrong given what we currently know. In a sense, it does detect pangrams, because the sentence we’ve given it is not a pangram and it identified that. We just haven’t given it an actual pangram. That “for any argument” part of my objection above imagines a world that we don’t live in. This function is correct in the world that we live in.

Third, this technique exposes bad designs. Maybe we go through a suite of assertions and find that we never had to improve this implementation. It happens. Maybe replace this function with a hard-coded false wherever it was called. Our design was based on an assumption– people are going to need to know if a sentence is a pangram– which was wrong.

Conclusion

I learned this technique via the late Jim Weirich’s ‘Roman Numerals Kata’ session at the Boston Ruby Meetup. It’s a masterclass. This video is hard to find and of poor quality, so I thought I’d add my interpretation.

Earn your TDD stripes by using tests to prove that your naive implementation isn’t good enough.

✉️ Get better at programming by learning with me. Subscribe to Jake Worth's Newsletter for bi-weekly ideas, creations, and curated resources from across the world of programming. Join me today!


Blog of Jake Worth, software engineer in Maine.

© 2022 Jake Worth.