[Prev][Next][Index][Thread]
Re: Dylan, MOP, object/relational mapping...
In Dylan you can't create bindings at runtime, so, in the very least you
must create a bunch of variables for your accessors up front. If you don't
create these bindings up front, then calls to accessors corresponding to
these bindings would give rise to undefined binding errors when
compiled. It would be pretty easy to write a program that read some
database schema information and produced these initial variables. But at
this point you might as well just define the generics instead of
variables. From there on in, you can do it all dynamically, meaning, you
could dynamically add methods to these generics based on the current
configuration.
As far as introspection goes, nothing beyond the introspection that is
specified in the DRM has be standardized on although both Gwydion and
Functional Developer provide an introspection module (albeit undocumented
in FD's case). For instance, Functional Developer provides a methods for
finding all the slots of a given class and then finding their accessors
etc. I can provide more detail if you're interested.
If you're really looking for the sort of dynamism that you've described
then I think using a single getter and setter for the database accessors
might be your best bet:
define open generic attribute-value
(entity :: <base-entity>, attribute :: <symbol>) => (value);
define open generic attribute-value-setter
(value, entity :: <base-entity>, attribute :: <symbol>);
then you define default methods on <base-entity> that perform lookups in
the database as you described. then you could write a class-definer macro
that allowed you to override these default accessors whenever you wrote a
subclass. it would basically expand into the usual class definition plus
delegator methods that specialize on singleton symbols as their attribute
parameters and that would translate attribute-value into a call to the
actual instance accessor:
define method attribute-value
(entity :: <widget>, attribute == #"height") => (value)
widget-height(entity)
end method;
this would then override the default attribute-value method. i think this
is similar to what neel was suggesting.
the disadvantage with this approach is that you need to use a mechanism
outside the usual accessor mechanism to access slots. with a little
macrology you can make this a bit more palatable:
define macro entity
{ ENTITY(?:name) }
=> { rcurry(attribute-value, ?#"name") }
end macro;
which would then allow you to access entity slots using the following syntax:
ENTITY(height)(x)
which might be a bit smoother than
attribute-value(x, #"height")
what you really need is something like a reader macro which would allow a
distinctive and succinct format for expressing our new dynamic
accessors. actually we had thought about such a read macro facility at
harlequin and i will reveal that in my next message...
Jonathan Bachrach
President, Functional Objects, Inc.