Clojure — Changing a data structure

Dan Pelensky
2 min readJul 25, 2017

--

In my IPM on Thursday, I was given feedback on my Clojure Tic Tac Toe. One of the bits of feedback I got was that I should change the data that I pass in to most of my functions.

What I was passing in was the state of the board in the form of a vector with the list of moves in order.

X played in the top left corner followed by O in the middle etc.

I’d set size as a constant, but was challenged to pass in size in the same data structure that I keep board in.

I ultimately kept it very similar, but pass in a Hashmap rather than a vector, and include the size in that.

I thought that since it was quite a small change, it would be quick and easy to implement. In actual fact, since I was passing this data in to most functions, it required a change to nearly every function to get my tests to pass again.

I started off creating a functional programming language approach to a getter method for both size and board:

(defn get-board [board-state]  
(get board-state :board))
(defn get-size [board-state]
(get board-state :size))

In each function where I use the board or the size, I’ll create a let to get the one that I need.

(defn game-tied? [board-state]
(let [board (get-board board-state)
size (get-size board-state)]
(and (= (* size size) (count board)) (not (game-won-by? "X" board-state)) (not (game-won-by? "O" board-state)))))

The problem, was that my functions use each other so much, that I made a change, and suddenly 10 tests would fail. I methodically changed my tests to use the new data structure, and then would look at the failures to see which functions were being called, and subsequently change those test.

All up, I think it took about two hours to make this relatively minor change but thankfully I ended up with all tests passing again.

In an object oriented language I would use encapsulation to ensure that a small change like this wouldn’t require such a major redesign of the entire codebase to change, but I’m still not sure of a better way of doing this in functional programming. Any advice please get in touch.

--

--