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.