> JavaGI: Inspired by Lämmel and Ostermann (2006), Wehr (2009) proposes JavaGI: a variant > of Java aimed at bringing the benefits of type classes into Java. JavaGI provides an > alternative viewpoint in the design space of type-class-like mechanisms in OO languages. > JavaGI has generalized and generalized interface implementations in addition to conventional
> OO interfaces and classes.
Your approach also seems close to C++ concepts, which are also discussed in the above paper.
Sandro[1] http://ropas.snu.ac.kr/~bruno/papers/TypeClasses.pdf <http://ropas.snu.ac.kr/%7Ebruno/papers/TypeClasses.pdf>
[2] http://www.stefanwehr.de/publications/Wehr_JavaGI_in_the_battlefield.pdf On 30/10/2013 6:29 PM, Jonathan S. Shapiro wrote:
As we've been going through the GC discussions, I've been thinking about type classes vs. (Java/C++) interfaces. The harder I think about them, the less semantic difference I see. I'm starting to wonder if a generalized variant of C#-style instances isn't a functional _superset_ of Haskell type classes. The main difference seems to be that interfaces are types and type classes aren't. Or more precisely, interfaces are /object/ types while type classes have only compile-time constant instantiations.Before I dig in to this, let me say that instances as specifically implemented in Java or C# obviously are /not/ a functional superset of Haskell or BitC type classes. But each time I run into something that looks like a functional deficiency in Java-style interfaces, I seem to find an easy way around it, so let me push on this a bit.* *Certain things are clearly (I think) /not/ differentiators between interfaces and type classes:The presence of self type /is/ a differentiator, because an interface can have non-static methods. Let's ignore that for a moment, and consider only interfaces that consist exclusively of static methods. If Haskell had a C#-style object type, that type could clearly be a type parameter to a TC instance. Another way to express this is to say that an Instance with non-static methods is instantiated over an encapsulated or existential 'this type parameter. Which is about what's happening, so that's not such a bad intuition. This is the heart of why interface instantiation creates an object. But as I say, stick with static-method-only interfaces for a moment.The difference in operator overloading mechanisms change the way overload resolution is performed, but I don't know that this changes anything fundamental. Assume, for the sake of argument, that we remove from the language the ability to directly overload operators with class methods or interface methods, and instead use some sort of mixfix introduction syntax. That will put both schemes on a common overload resolution framework. It might not be a /good/ framework, but the fact that it's common will hopefully prevent us from getting distracted by the operator overloading mechanisms.Finally, let's take the type inference strategy out of the picture, because we can use (or not use) similar inference strategies in both styles of language.* *I'm assuming a language in which first-class and/or anonymous procedures are possible. Thus, I assume an interface notion in which an interface type may include (non-virtual) procedure implementations. And I don't mean "default" procedure implementations (though those could be done too).I also assume that interfaces can be generic, in the sense that an interface containing a procedure implementation can thereby introduce type variables that are not resolved by the implementing class. The "missing" type parameters are supplied at instance cast time, and cause the instance procedures to be instantiated in a fashion very similar to TC instances. We can even imagine partial specializations, though that isn't essential to anything I'm going to say here.Finally, I'm assuming that we can do what I'm going to call "Koenig interfaces" (Andy'll be annoyed, but that'll give me a chance to see him and Barb again, so definitely blame Andy for this feature if we implement it ;-) ). That is: we can have a class C and an interface I that just happen to be compatible, in the sense that /if/ we had written "C implements I" it all would have worked out. But we can go a small step further by allowing something like:C implements I by { method binding implementations }Note that I am /not/ assuming a model in which C is a subtype of I. I suppose I'm assuming an implementation in which I is effectively a vTable declaration, and "c as I" is really an object instantiation that pairs the "this" pointer of c with a vTable pointer from I. So really, the cast from C to I is really just an object instantiation for a wrapper object.But once we view interface creation as object instantiation, it's really not a big leap to imagine writing:(B, C) implements I by { method binding implementations }except that we need to name the respective instances of B and C and provide a syntax for instantiation. Like, say (b, c) as I. Which kind of confirms that _Interfaces are just proxy objects with a lot of convenience sugar for one particular instantiation pattern_./Except/ that an interface consisting exclusively of static methods need not (indeed cannot) have an associated object. If SI (static interface) is such an interface, thenf : SI -> int32 doesn't really take a formal parameter at all.And the more I stare at this, the more I come to the conclusion that the "C implements I by ... " thing is proof of a type relation (over the type parameters of I) in exactly the same way that a type class instance is proof of a type relation (over the type parameters of the TC).There's even the same problem with the desire for multiple implementations. We can imagine an interface Ord that we might want to implement as an ascending or descending order.So in the end, I'm left asking whether it may be true that the only difference between TC's and Interfaces is that the lexical arrangement of the respective languages have different scoping rules, and the instantiation mechanism for interfaces guarantees a witness object so long as there is at least one non-static member. It seems to be that the "troublesome" cases are the "objectless" interfaces, which have all of the same problems that TCs have (as well as the same resolutions).Surely I'm missing something obvious here, and the relationship really isn't this straightforward!shap _______________________________________________ bitc-dev mailing list [email protected] http://www.coyotos.org/mailman/listinfo/bitc-dev
smime.p7s
Description: S/MIME Cryptographic Signature
_______________________________________________ bitc-dev mailing list [email protected] http://www.coyotos.org/mailman/listinfo/bitc-dev
