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.

Reply via email to