I've developed a library that I would like to be extremely flexible. My 
current iteration has a primary function, in a core namespace, that 
dispatches to multi-methods which are expected to be defined externally as 
plug-ins/modules. The issue at hand is determining the right way to do this 
given how namespaces work in Clojure.  A conceptual example follows (the 
project is not xmas related, but Tis' the season for such things):

(ns christmas.core)

(defmulti remove-items :id) 
(defmulti add-items :id)

(defn decorate [object instructions]
  (reduce
    #(->> %1
        (remove-items %2)
        (add-items %2))
       object instructions))

Doing it this way allows people to create their own modules in separate 
namespaces containing the appropriate method handling along with a unique 
id:

(ns whacky.module
   (require christmas.core))

(defmethod christmas.core/remove-items :whacky [spec object]
   (remove-whacky-items object spec))

(defmethod christmas.core/add-items :whacky [spec object]
   (add-whacky-items object spec))

Note that I also want the ability to mix and match in use.  i.e...

(ns sample.use
   (require [christmas.core :refer (decorate)])
   (require whacky.module)
   (require crazy.module))

(decorate 
    {:object "tree" :branches 50}
    [{:action "add" :id :whacky :type "lights" :num 4}{:action "remove" :id 
:crazy :type "ornaments"}}})

Originally I implemented it such that these methods would reside in their 
origin namespace (ie. not loaded back to christams.core) but that caused: 
circular namespace loading blowups (which could be mitigated via nasty 
macro hacks), major code redundancy issues (due to some required code 
scaffolding), along with overall ease of use concerns. And so here I am, 
with the above working, but still thinking there's got to be a cleaner way 
to do this. 

Have any of you folks created a truly flexible plug-in/module system, 
within Clojure, that can be shown? Can you point me to a project that you 
would consider representative of a best practice for doing such?

Overall I can't help think I'm missing some well defined abstraction that's 
already built. Here are some options I've considered:

1. deftype, defrecord and protocols: We're not decorating well defined 
objects. These objects have only a few shared conceptual dispatches, but 
other than that they are loosely defined at a high level through 
documentation guidance and dynamically defined within the object itself 
(which is just a map), and since each module manages its own code 
everything works according to its own set of instructions specs.

2. Building this as an application (storing dispatch code in a db) instead 
of making it a library. This is feasible, but I'm thinking the required 
user setup will lose all curb appeal. And this seems like a lot of work 
just to mitigate namespace management for multi-method dispatching.

Now that I think further, it feels more like a spec than a library, only 
I'm trying to provide a single entry point with some very minimal loosely 
defined dispatches acting as constraints.

Thanks for any helpful ideas/pointers.

Tim

Sent from my iPad

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to