I'm interested in implementing Radul/Sussman Propagators <DSpace@MIT> in Clojure. The key element of the propagator model are variables that accumulate the assertions (all "mutation" takes the form of assertions) that support their value. Two important sorts of functionality provided by propagators are that you can query them for what that support is and you can also revise/retract variables (propagators) and those values and their supports change accordingly.
While a straight port from Scheme is easily done, a much nicer approach would be to use Clojure's transactional sort of memory directly. I've read the Clojure documentation about it's several kinds of variables but I'm not yet clear on which one might be used to implement propagators or whether I will need some new variant for them. It is clear enough that the mutations will need to occur within a transaction, but is there a Clojure variable that has the necessary "hooks" to build up a suitable representation of the mutations that have occurred occur within a successful transaction?
Interesting thought! I implemented propagators some years ago (sometime soon after seeing Alexy Radul speak at a Lisp conference at MIT ~2009?). My implementation was mostly a direct port, but I used Clojure's agents to maintain propagator state.
If you use Clojure's transactional memory, then you'll end up using refs for propagators (refs are the only reference type that directly participates in transactions). In terms of tracking the changes to each ref, watches (see add-watch) will do the job. Note, however, that watches will be notified only once for a change in a ref's value in a transaction; the ref's in-transaction value may have changed multiple times, but those "events" don't escape into the world outside of the transaction.
Good luck! By all means, post to the main Clojure mailing list with a link to your implementation. :-)
I hadn't seen your implementation before and since I hadn't searched recently that prompted me to search again and it looks like this implementation by Michael Nygard is using refs and transactions in the way I had in mind: