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

Reply via email to