I'm fairly new to Clojure, so I'm still struggling to unlearn the habits of OO-programming. While using Stuart Sierra's component library, I've found the recommendation in the docs of using idempotent lifecycles very helpful. The unfortunate result is that every component then has the same pattern in its start and stop methods:
(defrecord SillyExample [...] component/Lifecycle (start [this] (if (custom-started-check? this) this (custom-start-logic this))) (stop [this] (if (custom-started-check? this) (custom-stop-logic this) this))) It adds some extra nesting and, potentially, duplication of the started check's logic. In hopes of making idempotent lifecycles easier to implement, I made the following protocol, which seems to violate the implementation inheritance philosophy of Clojure. (defprotocol IdempotentLifecycle (started? [this]) (safe-start [this]) (safe-stop [this])) (extend-protocol component/Lifecycle my.ns.IdempotentLifecycle (start [this] (if (started? this) this (safe-start this))) (stop [this] (if (started? this) (safe-stop this) this))) So then a use case would like more like: (defrecord SillyExample [...] IdempotentLifecycle (started? [this] (custom-started-check this)) (safe-start [this] (custom-start-logic this)) (safe-stop [this] (custom-stop-logic this))) This seems like an easier end-user experience, but it feels wrong to implement a protocol with another protocol. A more "Clojurey" feeling option would require changes to the component library itself: (defprotocol LifecycleStatus (started? [this])) (extend-protocol LifecycleStatus java.lang.Object (started? [_] false)) ;; Lifecycle protocol stays as-is (defn safe-start [component] (if (started? component) this (start component))) (defn safe-stop [component] (if (started? component) (stop component) this)) Then component would need to use safe-start/safe-stop in place of regular start/stop in the start-system/stop-system functions. Maybe this is better suited to an issue/pr on his repository, but I wanted to see if there were any comments from the community. Is there a better way to do this? Andrew Oberstar -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.