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