As I understand the problem in your example, you do have a definition for what an Insurable is, but it's implicit: there's no way to check whether an object is insurable and thus no way to check which parts of the code break when the notion of being Insurable changes. Luckily Clojure provides us with the tools needed to make the definition explicit.
In your Java example you used an interface to define what an Insurable is. In Clojure you can do the same with a protocol: (defprotocol Insurable (cost-to-replace-with-new [insurable])) (def insurable? (partial satisfies? Insurable)) Whenever you expect to receive an insurable, you can use a precondition to make this assumption explicit, like BG and Meikel suggested: (defn calculate-insurance [& insurables] {:pre [(every? insurable? insurables)]} ...) Note that the Insurable objects are completely abstract; we don't know or care what kind of data structure are used to implement them. This means that we can't build valid Insurables by accident, like you did in your example by calling FuncA to FuncE, but that's a *good* thing, because data structures built like that are very brittle, as you noted. To wrap up the example, here are a two very different implementations of Insurable. Note how everything is modeled in terms of domain concepts instead of "maps with keys :x, :y and :z". We manipulate the data structures with completely normal Clojure code, but keep the knowledge of those data structures in one place only instead of spreading it all over the codebase. This makes the code much more robust and amenable to change. (defn make-simple-insurable [cost] {:post [(insurable? %)]} (reify Insurable (cost-to-replace-with-new [_] cost))) (defrecord CompositeInsurable [parts] Insurable (cost-to-replace-with-new [composite-insurable] (->> (:parts composite-insurable) (map cost-to-replace-with-new) (reduce +)))) (defn make-composite-insurable [& parts] {:pre [(every? insurable? parts)] :post [(insurable? %)]} (CompositeInsurable. parts)) -- Timo -- 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