Developer Scratch Pad
Lisp challenge 16 — an example of abstracting in Clojure


For my pacman project I had the following implementation of the initial state:

defn start-game
“starts a game state”
[]
{:direction ‘left
:pacman { :x 0, :y 0}
})

I got to the point where I had to refactor direction into :pacman. This broke my some of my tests, which I had program against the specific implementation. Below direction-to returned a modified version of the map that start-game creates. With the previous implementation, this worked fine.

(testing “should change direction to direction given, right”
(is (= ‘right (:direction (direction-to ‘right (start-game))))))

Once I changed the implementation, the test broke. The fix was simple, but super ugly and hard to understand.

defn start-game
“starts a game state”
[]
{
:pacman {:direction ‘left :x 0, :y 0}
})

;; broken

(testing “should change direction to direction given, right”
(is (= ‘right (:direction (direction-to ‘right (start-game))))))

;; fixed, but awkward and ugly

(testing “should change direction to direction given, right”
(is (= ‘right (:direction (:pacman (direction-to ‘right (start-game)))))))

The solution to this problem was to write a function that would return direction when taking state as an argument.

(defn direction
“gets the direction of pacman”
[state]
(get-in state [:pacman :direction] )
)

Now the test can be written like this:

(testing “should change direction to direction given, right”
(is (= ‘right (direction (direction-to ‘right (start-game))))))

Which is a lot nicer to the eyes. Also, if in the future I must change the implementation of the state map as long as I change the direction function I will be okay since direction is the abstraction.