It's very handy that :keywords act as functions and maps do too: (:start voyage) => 5 (voyage :start) => 5
It's idiomatic Clojure, I think. I've been experimenting with a style of top-down TDD that puts off deciding about the "shape" of data as long as one can. [I hasten to add this is not a style for all problems: it's not what you'd use to come up with clojure.zip, for example.] Since Midje currently only lets you stub out vars, not keywords, using that particular style leaves you with code like this: (def start :start) (def end :end) (def circular? [voyage) (= (start voyage) (end voyage))) "Stubbing out keywords" can be done, which would give you the more (I think) idiomatic: (def circular? [voyage) (= (:start voyage) (:end voyage))) Question is: should I invest in doing it? Which depends on how much it's worth. Which leads to two questions: * Is the `def start :start` alternative so offensive to your eye that it'd make you reluctant to try top-down TDD? (Note that the keyword-ey variant comes out just fine from bottom-up TDD.) That matters to me, because after a decade of not understanding top-down TDD, I finally did, so I have the zeal of the convert. * What does it mean - to the reader - to see (:start voyage) in code as opposed to (start voyage)? What expectations does (start voyage) set up that (:start voyage) wouldn't? Midje is supposed to help with the whole principle-of-least-surprise thing. ** (:start voyage) could just mean "I didn't want to bother to write an accessor function". ** It could mean that voyage is a composite object with a distinct piece that is its start, as opposed to a calculation of some sort, and that the difference between the two is important. I'm wondering, though, if that distinction really makes sense. There is, first, the hoary old encapsulation argument: that you use explicit getters and setters on a Point so that the caller needn't care whether the underlying coordinates are cartesian or polar. And especially in a context of pure functions, where (f constant) will always have the same value, whether that's a stored, calculated, or calculated-and-memoized value seems irrelevant. ** It could mean "there are no nasty surprises here". I vividly remember debugging a Smalltalk program and discovering what I'd been ignoring as a simple getter actually had hundreds of lines of code behind it. Using a keyword as a getter wouldn't have misled me so. (:start voyage) also makes it clear that the code is fast, whereas (start voyage) allows for anything - perhaps a leisurely calculation involving database queries. ++ It could mean: "Picking good names is hard. Many words in English can be either a noun or a verb. Does (start voyage) mean 'commence traveling' or 'make a property of the voyage available'? (:start voyage) eliminates the possibility of that confusion, saving me some mental name-picking anguish." I'm interested in what you think when you see a keyword, and what it would mean if you didn't. (Sorry for the long note, but this way I get to use some of my B.A 1981, English Literature, background! http://en.wikipedia.org/wiki/Reader-response_criticism ----- Brian Marick, Artisanal Labrador Contract programming in Ruby and Clojure Occasional consulting on Agile www.exampler.com, www.twitter.com/marick -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en