This will need some cleaning up, and I'm sure you'll have questions. Derived index: =============================
To compute an index value derived from the current values of an instance, simply define a special slot with the argument :derived-fn. The derived-fn is a function name or form that will compute the derived value. An index is defined on this slot and the computed value is stored in the instance (not recomputed upon read). :derived-fn - the name or form of a function which computes the derived value and returns two values: the value and a boolean indicating whether it should be indexed or not :slot-deps - is a hint that restricts derived index updates to writes to the named slots. (defpclass foo () ((slot1 :accessor slot1 ...) (slot2 :accessor slot2 ...) (slot3 :accessor slot3 ...) (sum1-2 :reader sum :derived-fn my-derived :slot-deps (slot1 slot2)))) (defun my-derived (instance) (values (+ (slot1 instance) (slot2 instance))) t)) :index t is not necessary - in fact it is ignored. :slot-deps are also not required, but the derived index is updated on any slot write if that slot is not transient, set-valued or an association. We can add those last three slot types into the mix if necessary, but I'm trying to avoid too much complex computation taking place during slot writes (self-deadlock, etc) for the time being. Associations: ======================= One-to-Many associations: If class B has a slot that stores a single instance of A, then class A would like to have a method that returns the set of instances of B that refer to the instance of A. If A is person and B is job, then (slot-value job-inst 'owner is a reference to A and A->jobs is a method (no slot storage) that refers to an index on job->owner. The index keys are A oids. (defpclass person () ((jobs :accessor jobs :associate (job person)))) (defpclass job () ((person :accessor person :associate person) (title :accessor title ...) (company :accessor company ...))) The slot 'person in job behaves like an indexed slot. However, when you evaluate (jobs person-instance) you get the list of jobs that have person-instance as their person slot value. reading: Reads using slot-value or the accessor will return the appropriate associations. writing: (setf (jobs person-instance) job-instance) will set the slot- value of 'person for job-instance to the person-instance, removing any prior association. boundp: The slot 'jobs' is virtual, and therefore permanently slot- unboundp. remove: To remove an association, you can set the slot in the job class to nil or make it unbound. (get-associations instance slotname) => same as calling (slot-accessor instance) (add-association instance slotname associated) => same as calling (setf (slot-accessor instance) associated) (remove-association instance slotname associated) => removes the association from a virtual association slot only Many-to-Many: To add many-to-many relations, any A->B relation also requires that we can find the relation from the other direction B->A. Typically this requires a special table to keep track of pairs of related objects. You can then query on either column to get the set of related objects. This interface simply causes both sides to behave like the jobs slot of the person class above. (defpclass person () ((jobs :accessor jobs :associate (job person)) (defpclass job () ((persons :accessor persons :associate (person jobs)) (title :accessor title ...) (company :accessor company ...))) reading: (jobs pinst) (persons jinst) => returns the associated persons/jobs writing: (setf (jobs pinst) jinst) => will add jinst to the pinst jobs slot and pinst to the jinst persons slot. Writes to either slot results in a bi-directional association slot-boundp: both slots will return nil for slot-boundp The only way to remove a created association is to call (remove- association instance 'slot associated) on either associated instance. Note: schema changes between association slot types may be buggy and/ or cause data loss. Be careful! On Oct 19, 2009, at 4:20 PM, Alain Picard wrote: > Ian Eslick <esl...@media.mit.edu> writes: > >> Association slots were added recently and have not been fully tested. >> They should be considered in beta. >> >> If I send you a short description in the next few days will you >> volunteer to update the docs? :) > > Possibly, but I can't make promises. I might have a couple > of hours late next weekend, if you can get me the necessary > info by Friday. > > Cheers! > > --ap > > > _______________________________________________ > elephant-devel site list > elephant-devel@common-lisp.net > http://common-lisp.net/mailman/listinfo/elephant-devel _______________________________________________ elephant-devel site list elephant-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/elephant-devel