Don't call it monkey patching! We'll start to feel like we're in ruby, writing code that relies on modifications to Object :).
In certain languages you can create modular units which are incomplete, and require that the user supply custom functions and constants in order to create an 'instance' of the module structure. There, it's well defined and mathematical, and pretty neat; for example, we can have a equality module where all we have to do is give it a '<' function that knows how to compare a certain kind of data, and and we get back shiny and correct >, <=, >=, and = functions. Here's a way of doing it that might work in clojure, but looks kinda ugly: (defn equalifier "pollutes the namespace with relational operators derived from a custom less-than function." [<fn] (defn my< [a b] (<fn a b) (defn my= [a b] (not (or (<fn a b) (<fn b a)))) (defn my> [a b] (<fn b a)) (defn my<= [a b] (not (<fn b a))) (defn my>= [a b] (not (<fn a b)))) Now we can try creating a less-that function that compares numerical functions according to their value at zero, and derive the other relational operators from it: (equalifier (fn [f g] (< (f 0) (g 0)))) (my= #(* 2 %) #(* % %)) => true ; under our relation, 2*x '=' x^2 (my> (+ 2 %) (fac %) => true ; x + 2 is 'greater than' the factorial function over x Thus, we'll get well behaved comparison functions that do a specific sort of comparison, if we give it a less-than function that is itself well behaved. This approach is neat, except for 2 problems I've run across: 1) The function will just spew the names into the namespace, without any way for you to prevent collisions, or associate the functions with just one structure, so it's difficult to use to create multiple instances . 2) The function just defines functions to the namespace it lives in, which could probably be fixed by defining it differently. A macro, called like (module-inst myname-modulename & args) could let you do: (module-inst mystring-equalifier (fn [a b] (< (count a) (count b))) (mystring< "apples" "oranges") => true (mystring= "cat" "dog") = true Here, the macro has taken care of reading the module definition into the right namespace, and has renamed the module functions according the user's directive. Hehe, I haven't learned to write that macro yet. And anyways, this approach still feels a little unnatural, as though it's breaking the language's natural means of modularization. Could our modules be instantiated into their own empty namespaces, to better prevent collisions, or to be able to "pass" the module instance around the program by passing the namespace reference? Anyways, back to the gravity example. It feels kind of icky to give the user the option to change the function of a code library by changing constants, possibly while the library is being used.. that just blows the referential transparency of the library, without giving you multiple customized instances. However, the threaded approach seems a little different and more natural to clojure, and should work in the cases where you don't need to have two versions of the same library side by side, but that's another area of the language I haven't explored yet. I've been wondering about a similar problem, working with a little gravity simulator for a system of particles, where I'd like to be able to have the option of building a simulation where the particles have a different representation, or where the gravity constant is different, or a different integration scheme is substituted for the default. To that end, I had been thinking of using a map to store the resulting structure along with all its functions, but by the time I'd get to writing all the functions to interface with that, I'd have created a kind of light object system, and I don't know if that's the right thing to do :). I just thought of the idea of instantiating derived functions from modular structures now, and I'm not actually sure that this will work at run-time if it's done through a macro, so I'd like some feedback. And what do you guys think of storings fns in a map to achieve structure modularity? Finally, is it possible to write functions that duplicate and modify a namespace, returning a anonymous namespace which can be then imported to the current scope, or passed elsewhere? The last one sounds like a bit of what an MLer might mean when she says "Modules are first class in ML", minus nasty algebraic type notation :D - max suica --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---