[DGD] object types: examples from the kernel lib

Par Winzell zell at skotos.net
Mon Jul 12 11:55:24 CEST 2004


> Have you ever used function_object() as a way to make sure that an
> object can perform the role you want it to perform?  Then object types
> can simplify your work.  The kernel library presently uses object types
> in a few cases, which I will describe below by way of example.

An alternate perspective: for people who have not had much experience 
with more strongly typed languages (or who, like me, are merely subject 
to a lazy bent), using function_object() to check the precise type of a 
function's object parameters is too cumbersome to feel worthwhile.

In e.g. Java, an object that tries to call a function on an object will 
simply not compile unless the object is of a type undeniably known to 
implement F. It's not merely impossible to call a non-existent function, 
it is impossible for the code to even try.

LPC is much laxer. There is no compile-time check on call_other, of 
course, but there's also the LPC tradition that call_other() silently 
calls non-existent functions on another object without error. Thus we 
simply do not get any immediate visceral punishment when we screw up and 
call a function (or otherwise supply) an object of the wrong type.

We do, of course, get punished, because our code doesn't work. The whole 
point of type-checking is to catch errors at an earlier stage than mere 
faltering logic.

These new object types provide just that; better type checking. But they 
also provide incentive to arrange your code with much more structure. 
Where you're used to sending around blobs of code and data that are all 
just 'object' to the recipient parameters, start thinking of them as 
precisely defined data types.

Thus if a function accepts a parameter of type 'object "/lib/iterator"' 
this new DGD functionality allows you to rest more assured than ever 
that it will behave like (your idea of) a standard iterator. More than 
that, however, it will also compel you to go through your legacy code, 
finding all the iterators you've written over the years, and making them 
all inherit "/lib/iterator".

Next, in a passionate flurry of standardisation, you will find yourself 
going through all your data structures to give them the ability to 
return just such a standard iterator. And while doing that, you'll 
realize that if they are all iterator providers, they should inherit, 
say, "/lib/iterator_provider" or perhaps, Java-style, "/lib/collection", 
and suddenly you can write functions that accept "/lib/collection" 
objects which do not care a iota what the underlying implementation is 
and simply expect to be able to retrieve an iterator from whatever it is 
that was sent in.

Yes, of course, this is just basic object-oriented design, and we all do 
it more or less automatically. Some of you are undoubtedly even 
disciplined enough to do it without support from the language. Those of 
you who are more like me, however, and need good habits encouraged and 
bad discouraged, will find these object types simply thrilling. Aim them 
at your old monolithic monstrosities and see them dissolve into elegant 
type interactions.

Now, if /lib/collection could just be made abstract... :)

Zell

_________________________________________________________________
List config page:  http://list.imaginary.com/mailman/listinfo/dgd



More information about the DGD mailing list