Hi,

I'm new to clojure and lisp in general. I'm trying semi-porting a real
world application but at this time I lack patterns to reason about
clojure solutions to problems. I thought I'd ask the community about
one such problem I’m facing.

To give a simple example for the following discussion, suppose we have
the following:
- A "temperature" fact that is updated by some external connection to
a thermometer.
- A "heater on" fact that depends on the temperature. If the
temperature is, say, < 20 degrees true otherwise false.

- Requirements -
We want to have a collection of "facts", all mutable (i.e. they will
change over time).
Each fact is displayed in a GUI. So, there must be a callback
functionality for when the fact changes (observer pattern, GUI being
the observer).
Some facts are "standalone" while others are based on other facts. In
effect, these other facts are observers of the standalone facts (or of
other dependent facts).
Any component (GUI included) can change any fact anytime. When this
happens, all dependent facts must be recalculated and all observers
called.

I implemented this in Java like so:
- Fact class implements observer pattern (w/ PropertyChangeSupport)
- GUI linked to all facts through addObserver
- Rules based engine (drools) to update facts when they change (uses
addPropertyChnageListener/removePropertyChangeListener implemented by
facts). Whenever a fact change Drools refire rules (Drools handles
dependencies).

Drools is great but is rather heavy for my needs. My rules/
dependencies are really not that complicated. Besides, I would much
rather have them as a series of clojure functions.

***
At this point, I'm a bit lost trying to match these requirements to a
clojure design. I suppose:

- The facts must be referenced by some unique ID, probably a keyword.
- The Fact class should be ported to a structmap + related functions.
- Fact should include a function to set it. (If the set doesn’t change
anything, no callbacks are called).
- Fact should include a collection containing callback functions.
Anyone can hence “register” their callback. BUT: how to handle
unregistrations? Is this a simple matter of passing the same function
that was used to register?
- The dependencies are really not part of the facts themselves. I
should handle them as a series of clojure functions (or should I?).
E.g.:

(defn rule1 [] (set-fact :heater-on (> (get-fact :temperature) 20)))

- But should I also register dependencies myself? E.g:

(add-fact-observer :temperature rule1)

- Is there a way to make this automatic given that my rule (rule1)
already contained this information?

- And what about the GUI (in Java)? Basically, each GUI element knows
what fact it is bound to, so the GUI code itself drives the
addObserver’s. So, I would need to expose an interface in clojure.

(proxy someJavaInterface observer fact-in-java
  (fn [] (add-fact-observer fact-in-clojure (fn [] …callback
observer…)))))

- ??? How to make a mapping between fact-in-java and fact-in-clojure?

I could go on but I think that is more than enough.

Is my basic design sound? What about the questions I face? (Automatic
detection of dependencies, mapping between keywords and something java
can muster, etc.)

I’m really not looking for a complete how to, just general guidance in
the design. Of course, code fragments are always welcome. ;)

If you have made it this far, thanks!

Max

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