TDD in Clojure, part 2 (in which I recover fairly gracefully from a stupid decision)

Part 1
Part 3

I ended Part 1 saying that my next step would be to implement a function that counts the number of living neighbors a cell has. Given that we’re already pretending (through stubbing) that a living? function exists, living-neighbor-count is pretty trivial if we also pretend we’ve got a neighbors function:

Following my “mapping, like accessors, is too simple to test” guideline, I almost didn’t write a test. But what the heck:

Once the test passes, we need to write neighbors. To implement it, we’re going to have to take cells apart (to get x and y coordinates) and put them back together (to create neighbors). So I don’t see any point to using stubs and dummy variables like ...cell... in this test:

Boldly, I will here use one test to define both cell-at and neighbors (as well as the test helper have-coordinates that checks a list of cells against a list of coordinates).

(If I were more sensitive to that small voice in my head that warns I’m going astray, I would have heard something around now, but I ignored it. So we will too.)

Enter the REPL

My thought about how to implement neighbors has three steps, so I’ll try them out in the REPL. First, I’ll make (x,y) pairs to add and subtract from the original cell’s coordinates:

That’s good, except (0, 0) shouldn’t be in there. (A cell can’t be its own neighbor.) So I need to delete that:

(remove #{[0 0]} product) is a Clojure idiom. remove returns its second (sequence) argument, omitting any element that the first argument (a function) returns truthy for. #{x} is the set containing x. In Clojure, sets act as functions that return something truthy iff their single argument is in the set. That is:

Finally, I need a function that shifts a cell by an offset. For the REPL, I’ll pretend the cell is just an [x y] vector. (We have yet to define what it really is.)

I can build neighbors from what I’ve tried out. To make the test pass, I’ll continue to use vectors for cells, hiding them behind a simple functional interface of cell-at, x, and y.

The concrete representation of the cell — and disaster

Here are the functions as yet undefined:

There’s no more escaping it. I’m going to have to decide what kind of thing border produces. That thing has to be a sequence for tick to map over:

border's result is also stored in world where living? will use it to decide whether a given cell is alive or dead.

My first thought was that I could use the set idiom I used above—the bordered world could just be the set of all living coordinates. Sneakily, any location not in the set would represent a dead cell. That would be great for implementing living?, but it wouldn’t work for tick, which has to process not only living cells, but also the dead cells that make up the border.

So my fallback was for border to produce a map, something like this:

Maps are sequences, so you can map over them. But I don’t think I’ve ever actually tried it. What happens?…

OH GREAT. If I go down this route, we’ll have three different ways of representing cells:

  • as the original location in inputs like *vertical-blinker*: [0 1]
  • as part of a living/dead map: {... [0 1] :dead ...}
  • as a living/dead vector: [ [0 1] :dead ]

That’s intolerable. And yes, I bet at least half of my two readers thought I was mistaken not to think about data structures at the very beginning. However, my strategy with Clojure TDD has been to put off thinking about data structure as long as I can, and I’ve been surprised and pleased by how often I ended up with simpler data than it seemed I would. I’ve found that, given the use of globally-available immutable “background” data, much of what might have been explicit data structure–vectors of maps of vectors of…–ends up in the implicit structure of the computation. More about that, though, will have to wait for another post.

A recovery plan

The problem is here:

When I wrote that, I remember that the still small voice of conscience objected to the way I was both stashing the bordered-world away as background and simultaneously picking it apart with map. That just felt weird, but I argued myself into thinking it was harmless. It was not.

Really, since my whole program takes input [x y] pairs (such as *vertical-blinker*) and turns them into a different set of [x y] pairs, most of my work ought to be done with those pairs. I should be thinking about locations of cells, not cells themselves. In that way of thinking, border shouldn’t produce “cells”. It should take locations of living cells and produce locations that point to both living cells and adjacent dead cells.

Further, I shouldn’t repeat those locations in a world function. Instead, I need something that can answer questions about cells, given their locations. It should be a… (I’m bad with names)… an oracle about cells. I first imagined this:

using-cell-oracles-from should produce any wise and oracular functions we need. So far, that’s just living?.

I realized something more. Locations are flowing into the pipeline, locations are flowing out, and in this version, locations won’t be transformed into cells anywhere within the pipeline. That makes unborder, which was originally supposed to convert a mixture of living and dead cells into only living locations, seem kind of stupid. If tick produces only living locations, unborder can go away. (The name unborder always bugged me, because it didn’t really describe what the function would have to do. Once again, I should have paid attention.)

That leads to this top-level function:

That wasn’t so bad…

As it turns out, changing my mind about such a fundamental decision was easy.

What did I have to do to the code? I had to write using-cell-oracles-from. Here’s a test.

I won’t show the code that passes this test—it’s a somewhat grotty macro (but a simple transformation of the earlier against-background). You can see it in the complete source for this post.

I did a quick global-replace of “cell” with “location” and tweaked a couple of the resulting names. Although both you and I know that locations are just pairs, I retained the functions make-location (formerly cell-at), x, and y to keep the code insulated from the potential of another change of mind.

I had to convert the successor function to dead-in-next-generation?. That was pretty simple. I had to change two lines in the test. Here’s one:

To make that test pass, I had to rewrite successor. It used to be this:

Now it’s this:

That was just a matter of inverting the logic and deleting killed and vivified. (Before I ever got around to writing them!)

The ease of this change makes me happy. Even though I blundered at the very beginning of my design, the way stub-heavy TDD lets me defer decisions—and forces me to encapsulate them so that I have something to stub—made the blunder a not-catastrophe. I wish I could say that I blundered deliberately to demonstrate that property of this style of TDD, but that would be a lie.

Enough for today

Only one function remains: add-border-to. That’ll be pretty easy, but this post is already too long. The next one will finish up the implementation and add whatever grand summary I can come up with.

3 Responses to “TDD in Clojure, part 2 (in which I recover fairly gracefully from a stupid decision)”

  1. Exploration Through Example » Blog Archive » TDD in Clojure: a sketch (part 1) Says:

    […] Part 1 […]

  2. Today in the Intertweets (June 16th Ed) | disclojure: all things clojure Says:

    […] in #clojure Part 2 (in which I recover from a stupid blunder) (here, via @marick) — This is a second installment in a series of articles about TDD in Clojure […]

  3. Exploration Through Example » Blog Archive » TDD in Clojure, part 3 (one wafer-thin function; conclusions) Says:

    […] the top down (or from user interface in). It’s not that I don’t blunder—we saw one of those in the previous installment—but those blunders seem easier to recover […]

Leave a Reply

You must be logged in to post a comment.


  • Buying Cheap viagra pharmacy. Worldwide Rx, Best Prices. WorldWide Shipping.
  • Buy Cheap viagra purchase Online Best Online. No Prescription Needed.
  • Buy Cheap viagra gel jelly Now Low Prices. FDA Approved Rx: Online Pharmacy.
  • Buy Cheap bayer levitra professional pro Now Free Viagra Pills! Top Online Pharmacy.
  • Buy Cheapest on line pharmacy viagra Now Best Internet. Buy Medications Online.
  • Buy Cheapest when to take viagra Now Buy Medications Online. Free Viagra Pills!
  • Buy Cheapest taking 2 20 mg cialis Online Discount Online Pharmacy. Best Internet.
  • Buy Cheapest the cialis Now Buy Medications Online. WorldWide Shipping.
  • Buy Cheap cialis website Now Guaranteed Shipping. Buy Medications Online.
  • Buy Cheapest cialis discoun Online Cheap Prescription Drugs. Best Online.
  • Buy Cheap viagra cheap online Now Low Prices. No Prescription Online Pharmacy.
  • Buy Cheapest buying cialis Now Pharmacy Store. 24/Online Pharmacy.
  • Buy Cheap purchase viagra Now Online Medical Shop. WorldWide Shipping.
  • Buy Cheapest overnight shipping of generic cialis Now Cheap Pharmacy Online. Best Drugstore.
  • Buy Cheap cheapest price for viagra Online Best Internet. Cheap Pharmacy Online.
  • Buy Cheap mens viagra Now Internet Prices For mens viagra! Best Internet.
  • Buy Cheap genaric cialis Online Free Viagra Pills! No Prescription Needed.
  • Buy Cheap cialis best price Now Low Prices. Discount Online Pharmacy Shopping.
  • Buy Cheap bayer levitra samples Now Cheap Prescription Drugs. Pharmacy Store.
  • Buy Cheapest legal generic cialis no prescription Now Best Drugstore. Top Online Pharmacy.
  • Buy Cheapest but cialis in us Now Best Prices. Drugs, Health And Beauty.
  • purchase viagra in australia Online Without Prescription Best Internet. Low Prices.
  • Buy Cheap viagra best price Online WorldWide Shipping. No Prescription Needed.
  • Buy Cheapest how long does viagra last Now Pharmacy Store. Cheap Online Pharmacy.
  • Buy Cheapest mail order viagra in uk Now WorldWide Shipping. Online Medical Shop.
  • Buy Cheapest levitra canada Online Low Prices. 24/Online Pharmacy.
  • Buy Cheap generic viagra soft tab fast Online 100% Satisfaction Guaranteed. Low Prices.
  • Buy Cheapest does viagra work Online Low Prices. Cheap Pharmacy Online.
  • Buy Cheapest buy cheap viagra soft Now Top Online Pharmacy. WorldWide Shipping.
  • Buy Cheapest cheap generic cialis Online Pharmacy At The Best Price! Best Online.
  • Buy Cheap try viagra for free Online Discount Online Pharmacy. Pharmacy Store.
  • Buy Cheap cialis multiple orgasms Online Online Prices For cialis multiple orgasms! Best Prices.
  • Buy Cheap viagra drug interaction Online Special Prices For viagra drug interaction! Best Online.
  • Buy Cheapest online viagra sale Now Best Prices. Discount Online Pharmacy.
  • Buy Cheap cialis faq Online Top Online Pharmacy. Cheap Online Pharmacy.
  • Buy Cheap viagra discount retail Now 100% Satisfaction Guaranteed. Pharmacy Store.
  • Buy Cheapest generic cheap viagra Online Best Prices. Online Medical Shop.
  • Buy Cheapest viagra price Online Online Medical Shop. Pharmacy Store.
  • Buy Cheap viagra generika Online 24/Online Pharmacy. Pharmacy Store.
  • Buy Cheap cialis info Online Pharmacy Store. Top Online Pharmacy.
  • Buy Cheapest buy uk viagra Online Guaranteed Shipping. Pharmacy Store.
  • Buy Cheapest viagra cheap Online Drugs, Health And Beauty. Best Online.
  • Buy Cheap highest safe dose of levitra Online Drugs, Health And Beauty. Best Prices.
  • Buy Cheapest brand viagra without prescription Now Free Viagra Pills! 24/Online Pharmacy.
  • Buy Cheapest buy viagra pill Online Best Internet. No Prescription Needed.
  • Buy Cheapest buy genuine levitra online Online Cheap Online Pharmacy. Low Prices.
  • Buy Cheapest difference between viagra cialas and levitra Now Pharmacy Store. Discount Pharmacy Online.
  • buy online viagra viagra Online Without Prescription Best Prices. Best Internet.
  • Buy Cheap generic cialis softtabs Now Buy Medications Online. Online Medical Shop.
  • Buy Cheapest cialis 36 hours Now 24/Online Pharmacy. Best Drugstore.
  • Buy Cheap viagra info Online Cheap Pharmacy Online. Free Viagra Pills!
  • Buy Cheap bayer levitra online pharmacy Now Best Prices. Special Prices For bayer levitra online pharmacy!
  • Buy Cheapest buy levitra us Now Pharmacy Store. Internet Prices For buy levitra us!
  • Buy Cheap cialis long term effects Online Best Drugstore. Guaranteed Shipping.
  • Buy Cheap cialis sample Online Top Online Pharmacy. Pharmacy Store.
  • Buy Cheapest order viagra now Now Online Medical Shop. Top Online Pharmacy.
  • Buy Cheap discount generic cialis Now Buy Medications Online. WorldWide Shipping.
  • Buy Cheapest levitra professional overnight delivery Online WorldWide Shipping. Best Drugstore.
  • Buy Cheap how many people use cialis Now Best Internet. The Largest Internet Pharmacy.
  • Buy real cialis Online Without Prescription. Best Prices. Best Online.
  • Buy Cheap taking viagra after cialis Now Drugs, Health And Beauty. Best Internet.
  • Buy Cheapest levitra web sites Now Best Drugstore. Cheap Pharmacy Online.
  • Buy Cheapest generic for levitra Online Free Viagra Pills! Online Medical Shop.
  • Buy Cheap cialis oral Online Special Prices For cialis oral! Pharmacy Store.
  • Buy Cheap buy 10 mg cialis Now No Prescription Needed. Pharmacy Store.
  • Buy Cheapest female use viagra Now 24/Online Pharmacy. Best Drugstore.
  • Buy Cheapest cheapest generic viagra Now WorldWide Shipping. Top Online Pharmacy.
  • Buy Cheapest buy brand name cialis Online Top Online Pharmacy. Best Online.
  • Buy Cheap levitra fda Now Top Online Pharmacy. 24/Online Pharmacy.
  • Buy Cheap discount priced viagra Now No Prescription Needed For Drugs. Best Online.
  • Buy Cheapest online drug purchase levitra Now Low Prices. Top Online Pharmacy Supplier.
  • Buy Cheapest purchase cialis Now Top Online Pharmacy. Cheap Pharmacy Online.
  • Buy Cheapest levitra alpha blockers Now Pharmacy Store. Drugs, Health And Beauty.
  • generic viagra online Online Without Prescription Best Drugstore. Low Prices.
  • Buy money order viagra Without Prescription Doctor. Best Internet. Best Prices.
  • Buy Cheapest cialis levia and viagra Now No Prescription Needed. Best Drugstore.
  • Buy Cheapest order viagra on line Now Best Internet. Discount Pharmacy Online.
  • Buy Cheapest viagra pills Online Discount Online Pharmacy. Best Prices.
  • Buy Cheapest find cialis Online Pharmacy Store. Cheap Pharmacy Online.
  • Buy Cheap viagra prescription Now No Prescription Online Pharmacy. Best Online.
  • Buy Cheap where can i buy viagra online? Now Top Online Pharmacy. Cheap Online Pharmacy.
  • Buy Cheap buy viagra online pharmacy Online Best Online. 24/Internet)(safe Pharmacy.
  • Buy Cheap find cialis from mexico Online Online Medical Shop. Best Drugstore.
  • Buy Cheap viagra doses Now No Prescription Needed. Guaranteed Shipping.
  • Buy Cheap can young people take viagra Now Best Online. The Largest Internet Pharmacy.
  • Buy Cheapest buy cialis Now Best Prices. Cheap Prescription Drugs.
  • Buy Cheap pills viagra Now Free Viagra Pills! Discount Online Pharmacy.
  • Buy Cheapest order generic cialis Now Top Online Pharmacy Supplier. Low Prices.
  • Buy Cheapest viagra cialis store Online Low Prices. Cheap Online Pharmacy.
  • Buy Cheap levitra viagra cialis Now 24/Online Pharmacy. Cheap Pharmacy Online.
  • Buy Cheap cheap cialis sale online Now Top Online Pharmacy Supplier. Pharmacy Store.
  • Buy Cheap information cialis Now WorldWide Shipping. Discount Online Pharmacy.
  • Buy Cheapest mail order viagra online Online Cheap Pharmacy Online. Best Internet.
  • Buy Cheapest price of levitra Online Online Prices For price of levitra! Best Prices.
  • Buy Cheapest what is better viagra or levitra Now Discount Pharmacy Online. Low Prices.
  • Buy Cheapest what does viagra do to females Now Cheap Online Pharmacy. Free Viagra Pills!
  • Buy Cheap female version viagra Online Pharmacy At The Best Price! Best Internet.
  • Buy Cheap viagra without a prescription Online WorldWide Shipping. Free Viagra Pills!
  • Buy Cheapest levitra professional overnight delivery Now Drugs, Health And Beauty. Best Drugstore.
  • Buy Cheapest buy cialis without a prescription Now Best Drugstore. Discount Online Pharmacy.