[Prev][Next][Index][Thread]

Re: Dylan & object/relational mapping



Gail Zacharias wrote:
> 
> First, the fact that Dylan doesn't allow you to use static syntax to
> refer to dynamic data is not necessarily a bad thing.  It's good
> software engineering.  If Dylan allowed your program to say x.Foo
> without defining or importing Foo, then neither the compiler nor
> future readers and maintainers of your code would have a clue as to
> whether you, the author, expected that Foo will be an accessor defined
> at runtime by a database, or whether you meant to type x.Fou and just
> made a mistake.  This sort of thing might be useful during
> development, and it might be worthwhile to think about how the
> Interactor could help support that kind of experimentation, but it
> really doesn't belong in production code.  

I would argue that it's not good software engineering to require keeping
the definition of the same item (entity and its attributes) synchronized
in multiple tools. Future readers and maintainers of the code had
_better_ have access to the database design; if they have to infer it
from the source code there's going to be trouble no matter what!

> It does not in any way
> diminish the abstraction of your code to have to say somewhere 'define
> database-accessor Foo;' or something to that effect, if you really
> want to use static (compile-time) accessors.

I just don't want to do them one at a time. Given that I have already
defined the database schema and its mapping to objects, I wish to say
somewhere 'define accessors for all attributes of all entities in this
model'. Think of it as sophisticated laziness ;-)

> I'll just mention that the product formerly known as Harlequin Dylan
> internally has a project tool plug-in architecture that in theory
> would allow you do generate these accessor definitions at compile
> time, by reading the database schema at compile time. This is similar
> to how CORBA IDL and COM/OLE type libraries are handled.

That would be ideal. It does require some care in design to create a
system where generated code and customized code do not (can not) have
any conflicts, ever, under any circumstances. But I think it can be
done, perhaps more easily in Dylan than most languages.

> But I think the most natural way in Dylan to express the situation you
> describe is with dynamic symbolic accessors.  I.e. rather than saying
> x.Foo, you would say x[#"foo"].  This is explicitly saying that you
> are looking at a dynamic (run-time) lookup rather than static
> (compile-time) lookup.  The way you get to use the table syntax is by
> defining an 'element' method:
>   define method element (x :: <eo>, what :: <symbol>, #key default)
>      get-value(x, what)
>   end;
> and similarly for element-setter.

I still don't like the distinction. I'm tired of dealing with the
mechanics of database manipulation at the low and pathetic level of
abstraction provided by most tools. So my quest is not merely to raise
the level of abstraction, but to completely encapsulate the database
access to the point where application code just manipulates regular
Dylan objects. And of course I want to do that with as little unecessary
and redundant work as possible, or rather: as little work as possible,
period.

> Using this symbolic syntax does not prevent you from using the full
> power of the object system, and it does not prevent you from
> custom-coding accessors.  That's because Dylan has (1) multi-methods
> and (2) symbolic singleton specializers.

Yes. The capabilities of Dylan make that alternative much much less
objectionable by offering the ability to hide those implementation
changes from clients. But it doesn't feel right to me. You start with a
scheme where clients clearly see that database attributes are different
than class slots. Then you add the ability to mask the distinction in
selected cases as attributes change to slots or vice versa. Granted, a
client should never, ever, depend on the distinction. (In fact, there
should be no possible way for a client to be dependent on that detail.)
But it still seems muddled to me.



References: