I've been working on a library for representing molecules, atoms, chemical
bonds, etc... called chemiclj ( http://github.com/slyrus/chemiclj ) and I've
run into a design issue that has flummoxed me for a few weeks. I've written up
a blog post that goes into more detail (
http://slyrus.github.com/2010/08/27/chemiclj-namespaces.html ) but the short
version is that I'd like to be able to have an "external" interface, defined by
things that live in defprotocols, I'd like to have a "private"-ish
implementation of records that implement (is that the right term?) these
protocols, and then I'd like to have some "external" helper/constructor
functions for creating instances of these record types.
It seemed like the clojure-y thing to do here would be to have a chemiclj.core
package that defines the protocols, and to have chemiclj.atom and
chemiclj.molecule for the details of atoms and molecules, respectively. But
then how to get the make-atom function, for instance, defined in the
chemiclj.core namespace _after_ the chemiclj.atom has been loaded? The approach
I've come up with is to make a defn* macro that defines a function in the
specified package:
(defmacro defn* [fn-name & rest]
`(intern (if ~(namespace fn-name)
(symbol ~(namespace fn-name))
(ns-name *ns*))
(symbol ~(name fn-name)) (fn ~(symbol (name fn-name)) ~...@rest)))
and then in another ns, say chemiclj.molecule, one could do:
(defn* chemiclj.core/molecular-formula [mol]
(apply str
(map #(str (:id (first %)) (second %))
(sort-by #(:id (first %)) (count-elements mol)))))
which would cause molecular-formula to be defined in the chemiclj.core ns.
This, along with some load forms from the core.clj lets things work as I
expect/intend, but it's somewhat hacky/ugly. I was wondering if others have run
into similar ordering issues brought about by protocols/records/nses and if
anyone has any suggestions on what good clojure design aesthetics suggest here.
Thanks,
Cyrus
--
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