How to decide when indirection is worthwhile?


I am working on a personal project with a lot of map objects, and I often wonder whether I should access their data directly using get-in or write my own accessor functions. For example here is the schema I wrote for a “board” object (in a game of Texas hold’em)

(def Board
  {:cards {:p1 [Card] :p2 [Card] :table [Card]}
   :phase (s/enum :pre-flop :flop :turn :river :showdown)
   :winner Player})

A Board is only one key in a Game object whose code is in a separate namespace.

Is it worthwhile to write accessor functions like “phase”, “p1-cards” “winner” to be required and used in the higher-level Game namespace, or is it not worth it since you can almost as easily write (:phase board), (get-in board [:cards :p1]), etc?


Hi @prbroadfoot,

That’s a really great question. I think it is very common for people to use keywords all over the place. But in my experience, people soon regret having the structure of their data spread all over the codebase. It is far better to name a function that extracts the data, even if it is only a single keyword. It helps your code last longer and be more readable.

Just as a bit of support for this, I like to refer to Structure and Interpretation of Computer Programs. Such a great book for so many reasons.

When they’re defining the interpreter, look how many functions they define that are simply defining the structure of the syntax. Here are a few examples:

(define (variable? exp) (symbol? exp))

(define (definition? exp)
  (tagged-list? exp 'define))

(define (if? exp) (tagged-list? exp 'if))
(define (if-predicate exp) (cadr exp))
(define (if-consequent exp) (caddr exp))

My rule of thumb is: if you’re adding meaning, give it a new name.



Thanks Eric, that makes sense. I suppose the time it makes most sense to use keywords is when you’re dealing with data whose structure is fundamental and highly unlikely to change, like Ring maps. But besides that it’s better to name functions to extract data.

I agree SICP is an excellent book, I’ve been reading it recently and am currently on Chapter 2.