[elephant-devel] What to use, what not to use...

Ian Eslick eslick at media.mit.edu
Tue Oct 20 00:36:03 UTC 2009


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 <eslick at 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 at common-lisp.net
> http://common-lisp.net/mailman/listinfo/elephant-devel





More information about the elephant-devel mailing list