Just to be clear, by "mixin" you're referring to merging two maps of functions?
Have you considered using composition instead of mixins? - James On 23 November 2015 at 20:01, William la Forge <laforg...@gmail.com> wrote: > When an object is built from a map, aggregating mixins is a trivial > operation. But when a mixin needs to be closed, it is better to have a > common mechanism to manage a stack of the close functions of all the > aggregated mixins than to depend on application logic to do so. Case in > point, I'd like to use an actor mixin or an alternative async channel mixin > when composing a database. The async channel mixin will require a close but > the actor mixin will not. So I developed the closer mixin to handle the > calls to both the async channel and db file close functions. The database > will only know the closer's do-close method. And it is the responsibility > of the async channel and the db file mixins to register their close > functions with the closer mixin. > > > My inspiration is Stuart Sierra's component library > <https://github.com/stuartsierra/component>. But I am not handling > dependencies per say, only managing a stack of close functions. And the > "components" are only functions and atoms added to a common map structure, > not records or deftypes. The result is a very lightweight pattern for > components. The closer code itself is a lock-free mixin that gets added to > the common map as needed when the on-close method is called. > > For more information, see Closer > <https://github.com/laforge49/aatree/wiki/Closer>. > > (ns aatree.closer > (:require [clojure.tools.logging :as log])) > > (set! *warn-on-reflection* true) > > (defn on-close [f opts] > (let [fsa (:closer-fsa opts)] > (if fsa > (do > (swap! fsa > (fn [fs] > (if fs > (conj fs f) > (atom (list f))))) > opts) > (assoc opts :closer-fsa (atom (list f)))))) > > (defn- do-closer [fs opts] > (when fs > (try > ((first fs) opts) > (catch Exception e > (log/warn e "exception on close"))) > (recur (next fs) opts))) > > (defn do-close [opts] > (let [fsa (:closer-fsa opts)] > (if fsa > (let [fs @fsa] > (if fs > (if (compare-and-set! fsa fs nil) > (do-closer fs opts) > (recur opts))))))) > > -- > 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. > -- 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.