I’ve been thinking about this more, and I think I’ve come up with a reasonable syntax for this. There are still a few annoying cases that I haven’t worked out yet with regards to the intended semantics, but I think this would be a good interface for the majority of use-cases.
I’ve thrown together a simple example of what I’d like this to look like here: https://gist.github.com/lexi-lambda/6883bb6d72a3d6ca9988 <https://gist.github.com/lexi-lambda/6883bb6d72a3d6ca9988> The basic idea is that interfaces can inherit other interfaces. The semantics of this are as follows: An interface that inherits another interface automatically gains all of the inherited interface’s methods. Therefore, implementations of the sub-interface can provide super-interface method definitions in the sub-interface’s #:methods clause. The inheriting interfaces may provide default implementations of super-interface methods. Just like fallbacks, these can be overridden by specific implementations, but they’re used if those aren’t provided. Combining the two above points, sub-interfaces may also provide more specific method implementations that override super-interface fallbacks, even if those methods are part of an inherited interface. I can only think of one annoying possibility when dealing with this sort of inheritance, and that’s the classic diamond problem. This is effectively multiple inheritance. As with other instances of multiple inheritance, I think the reasonable approach would be to require implementors which have two possible inherited implementations to provide an explicit implementation that overrides both of them. Of course, this also means that it needs to be possible to refer to specific implementations of a given interface if needed, but this would be fairly straightforward by creating additional bindings that refer specifically to individual implementations. (To make this reasonable for the user due to the possible number of generated bindings, a generics-out provide transformer would be in order.) This solution accommodates a number of problems I’ve run into when attempting to create a solid generic collections library. This eliminates the unresolvable circular dependency between generic interfaces when fallbacks must be used to simulate sub-interfaces but the two interfaces are declared in separate modules. It allows user-defined sub-interfaces to extend existing interfaces without having direct access to the original interface declaration (which is required for the fallback-based method). It prevents the redundant prefixed naming hell I ran into when implementing sub-interfaces. If you look at my current implementation of generic collections <https://github.com/lexi-lambda/racket-alexis-collections/blob/master/alexis/collection/sequence/constructed.rkt>, you’ll see that the interface contains a lot of prefixed names (cons-ref, cons-append, cons-map, etc.). Since generics inheritance allows sub-interface implementations to reuse the super-interfaces’ method names, this prefixing is unnecessary. I’m not sure if anyone on this mailing list would have any feedback, but I figured I’d type this up just in case, as well as to document my current model. The hard part, obviously, would be figuring out how to implement this on top of the existing generics model. After some consideration, I think building this into the generics system rather than trying to implement it via some form of complex de-sugaring would be necessary from both an practicality and feasibility point of view. Any thoughts would be welcome; otherwise I may try and begin deciphering the racket/generic code to figure out how it ticks so I can figure out how to actually implement this. I think it would be a valuable addition that would make the generics system considerably more powerful. Thanks, 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/41ABB258-0446-433F-8020-A0BB0C49CD76%40gmail.com. For more options, visit https://groups.google.com/d/optout.
