On Tue, Mar 23, 2010 at 7:15 PM, Jonathan S. Shapiro <[email protected]>wrote:
> OK. I think I can now state what has made me uncomfortable about the
> Oliveira class notion. I do not say that I *should* be uncomfortable;
> only that I can now say what has been itching at me. In brief: the
> Oliveira classes (O-classes) are *too* abstracted. They correspond far
> better to Java/C# Interfaces than to conventional classes. Interfaces
> are a fine thing to have, but they are an insufficient answer for
> BitC.
>
Yes, they are purely interfaces. They correspond pretty much directly to the
trait in Scala.
>
> If you start from a C++ background, it seems very natural to ask:
> shouldn't classes subsume structures/records, and it seems natural
> that the answer to this should "obviously" be yes. O-classes do not
> have this subsumption property, and in consequence, they will carry a
> high runtime performance overhead. An O-class defines a dictionary, so
> in general its "methods" must be invoked through a dictionary with the
> associated costs of that invocation. More problematic, an O-class has
> no fields, so simple getters and setters have prohibitive cost.
>
>
They have an important subsumption property that makes this work
efficiently. We can treat the O-Object as a struct, but we must, in
addition, subsume whatever implicit or explicit objects are required to
fufill the interface. An important point is that any additional constraints
alter the type of the object.
The basic terms are directly transferrable to c++ via classes and (c++)
traits. GADTs will take a bit more work, but I like the idea of their
inclusion, because GADTs and dependent types would go a long way to proving
a system correct.
// Warning copious amounts of C++ ahead (probably won't compile, but it's
close)
// (O) class Set a where ...
template <typename T>
class Set : public T
{
virtual bool member(T&) = 0;
virtual Set<T>* merge(Set<T>*) = 0;
virtual Maybe<T> extract(T) = 0;
virtual Set<T>* insert(T) = 0;
}
template<typename T>
class IsEqable
{
public:
static void Constraints()
{
Bool* (T::*test1)() const = &T::operator=
}
Equatable() { void (*p)() = Constraints; }
};
// object ListSet :: Eq a => [a] -> Set a
template <typename T>
class ListSet : Set< IsEquable<T> >
{
implementations of members.
};
///////////////////////////////////////////////
This has some runtime dynamism, specifically hits to the vtable if ListSet
is referenced
as a Set< IsEquable<T> >
But note that it can't ever be referenced as a Set, it carries the
implementation in its type.
This did require single inheritance. But it can also be achieved without
single inheritance by
creating a constraint trait that is something like SetLike<T>
and have ListSet be a function which binds the approprate function pointers
to a struct
and return it as a SetLike < IsEquatable<T> >
The important type information would still be present.
This of course used some compiler hacks to enforce constraints which the
BitC compiler could provide in a much more elegant and concise manner.
> I'm a bit disgusted that I seem to have mangled Oliveira's ideas back
> into exactly the sort of C++/C#/Java style of object system that we
> all have negative feelings about...
>
>
This is not the traditional C++ type system, but the C++ system that morphed
into its present state via series of hacks, because the original system
didn't provide the assurance about types that we need. The kind that is
spelled out so elegantly in Oliviera's work.
Boost is a monolithic testament to both the power of the metaprogramming
system and the inadequacy of the C++ object system.
>
> If we were starting over, I'ld really prefer interfaces and interface
> inheritance.
>
>
I guess this boils down to whether compile time assurance is enough, or if
you want to have a physical (via vtable or whatever) link back to the
methods of the interface.
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev