He mentioned how much he was getting out of namespaced keywords, and a few us nodded and chipped in our own examples, and James made a comment (and I apologise to him for the paraphrasing, and invite clarification!) about how he so far hasn’t felt the need to reach for any way of representing his solutions except as plain data and functions, which often happens in Clojure — especially with the simpler stuff people like me do day-to-day.
But there sounded a tiny klaxon in my head, mainly because his problem-space sounded richly complex to me, and I blurted out some unformed thoughts about how you lose something when all you have is assoc and merge. I was jetlagged last night and there wasn’t much substance to my thoughts, but this morning I’m still curious about the question of what exactly you lose when you give up on e.g. using the power of Lisp to write a DSL, and how to make the trade-off.
My personal guideline is that I only prefer data after I have bound the problem to a well-understood domain. That means that I have to write the program first in code, using functions, before I realize that, yes, this could be described very succinctly and declaratively as data. This took a long time and lots of mistakes to understand. I essentially will only refactor to a data-driven approach after I already have it written and working.
But I still don’t feel like I understand when to write a DSL instead of just using data and functions. What sort of problem justifies the cost? When are the tools of composition we get with functions and maps not enough?
Personally I’ve never found the need to write one (although definitely the desire — I have a tendency to over-abstract that I fight daily), which makes me think I should spend more of my time looking for harder problems.
In any case, I’d love to hear James’s thoughts, and those of anyone else who feels like chipping in.