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 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

Reply via email to