Subject: Re: Typing collect
From: Jonathan Aldrich (jonal@cs.washington.edu)
Date: Mon Jan 17 2000 - 13:17:32 PST
> Meanwhile in our world, currently we use "signature constraint" (Craig's
> idea, of course) and copy_empty...
> As for the type system for Diesel, the existence of this workaround
> motivates me to have a syntactic sugar to abbreviate constraints (so that
> the above three constraints were much shorter and didn't cause
> inconvenience to the programmer), rather than to support parameterization
> over parameterized types (`T[`R]). But I am open to stronger arguments.
> It may actually be not that difficult to handle such parameterization
> either, but I am not there yet to try.
So here is the "workaround code" that I came up with, using Vass and
Craig's suggestions:
----------------------------------
-- for each MyCollection <= Collection define:
signature copy_empty[`R <= WhatMyCollectionCanHold](c@:MyCollection[S])
: MyCollection[R]
where signature new_my_collection[R]();
method map(c@:`T <= Collection[`S], cl@:&(S):`R):CR
where signature copy_empty[`R](T):`CR {
{
let result := copy_empty[R]();
c.do(&(e:S) {
result.add(cl.eval(e));
});
result;
}
----------------------------------
Can the existing typechecker handle this kind of thing? The `CR in the
result of the where-clause signature is pretty "out there." The
WhatMyCollectionCanHold restriction is another interesting typechecker
twister. Also, I don't think you can define copy_empty[R] very easily
with multiple signatures and a single method (I'm open to being proved
wrong with a code snippet).
This workaround might be acceptable for a small library. But it really
does seem silly to have to put the method in for every subclass of
Collection, and would probably be too painful in a large extensible
library with many functions like map. I think my original solution was a
bit more natural, and cleaner (though of course it wasn't legal Cecil).
> On the implementation side, the operation "create a new empty object of
> the same kind as the argument" has long been in the future work categories
> of "object model" and "object factories." I think that "object model"
> implies language support where "factories" implies simply some conventions
> and implementations of the factory methods for each class (which could be
> just sugars in some cases).
It seems eminently clear that we need at least enough object model support
to allow immutable (or "assign-once") fields to be initialized in a
constructor method, rather than in an "object isa" statement. Look at
bitset.cecil for the perfect example of why this is needed: to inherit
from a bit set, you need to initialize the "members" and "cached_length"
fields in the new method of the descendant--thus all descendants of
bit-set have to muck with ugly implementation details. This object model
fix could even let you add objects one-at-a-time into immutable
collections (in the constructor, of course!)
Some kind of factory system would also be very nice; a built-in sugar
would encourage people to use it. A good factory system would mitigate
the other problem you mentioned, that you can't say "object isa T" where T
is a type.
Jonathan :-)
This archive was generated by hypermail 2b25 : Tue Oct 03 2000 - 15:21:20 PDT