So as it turns out, I have found myself sorely wanting generic interface support in Typed Racket. I understand that the class/object system seems to be the usual method of implementing interface-like polymorphism in Racket, but I actually much prefer the style of polymorphism that generics have to offer.
I am looking into how difficult the task of implementing generics would be in Typed Racket. As a preliminary step, I’ve reimplemented the parsing of define-generics to allow for type annotations in prims.rkt, but of course, that’s the fun part, which doesn’t take very much work. :P Supporting the full set of features generics have to offer is a fairly daunting proposition, so obviously I’d want to work on getting a useful subset of the features instead. As far as I can tell, this can be subdivided into a set of smaller goals. The simplest implementation would be one that would only work within typed code, would only work on structs that explicitly implement the generic interface, and would not support #:defaults of any kind. First, this obviously requires introducing a “generic” type that would be defined by a new typed define-generics special form. This seems relatively straightforward—it should just declare a new type and a set of functions that use that type. Also, the struct special form needs to be modified to support #:methods. The internal structure type would need to somehow be extended to include information about what interfaces it implements. Ideally, I’d prefer that generic types simply be disparate types, and structs that implement these types would become subtypes of the generic types. I’m not familiar enough with the type system to understand how feasible that would be. Generics absolutely need to be polymorphic. I think an implementation of generics without parametric polymorphism would be a stunted one at best. It would be cool to add support for #:defaults on all types that can be converted to flat contracts/predicates. Rather than supplying a predicate, one would supply a type, and occurrence typing would make using these pretty wonderfully simple. This isn’t something I’ve considered at all, beyond the basic concept of how I’d like it to work. On the topic of interacting with untyped code, it would be nice to have a #:generics form in require/typed and an extension to #:struct to allow those to be used. I think all the machinery exists in terms of contracts, it would just need to be implemented. I actually don’t care about this all that much because I don’t find the use of generics to be very prevalent throughout existing Racket code. Obviously, it would need to be implemented eventually, but I would find immediate uses for generic support that would only function within typed code. In fact, wanting to use generics in a personal project of mine was what prompted me to look into this. What I’m interested in finding out are some answers to the following questions: For those familiar with Typed Racket’s internals and implementation, how much of an undertaking does this appear to be? Would this be completely out of my grasp, or would it even be worth my time to look into? Similarly, if I began working on this, would anyone be willing to at least give me some pointers as I work through attempting to implement things? I’m still rather unfamiliar with the code base as a whole, but I am interested in putting in the effort to learn—I would just need to be able to ask questions… probably a lot of questions. For anyone at all, even those who never use Typed Racket, how much would you care about generic interface support in TR? A lot of things in Racket seem to theoretically support generic interfaces, but I don’t seem them used very much. Does anyone have any personal experience using them, or are they something of an unpopular feature in general? I apologize for the wall of text. As a worst-case scenario, feel free to let me know that this is a project that’s probably too big for me to undertake at the moment, or that people are generally busy with other things. (I’m not being sarcastic, that’s a valid concern—sometimes that’s not clear in text-based communication.) As a final note, I have a silly little branch in my fork of typed racket with the tiniest start of an implementation here. If I start working on this, that’s probably where the code will be. https://github.com/lexi-lambda/typed-racket/tree/typed-generics <https://github.com/lexi-lambda/typed-racket/tree/typed-generics> Thanks for any and all feedback—I’m definitely interested in helping to bring generics to TR, but I also can’t really escape the feeling that I’m in over my head on this one. Alexis -- You received this message because you are subscribed to the Google Groups "Racket Developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-dev/347840BA-1D00-4FD9-8CA1-F4194AB963D6%40gmail.com. For more options, visit https://groups.google.com/d/optout.
