Remix.run Logo
atq2119 a year ago

Right, but what I'm describing is a tradeoff point that's between the extremes, where implementations are unnamed but can still be explicitly imported.

Making my example more explicit, you'd need syntax along the lines of

    // inside crate C
    use A::impl std::hash::Hash for i32;
This syntax would explicitly be limited to orphan implementations.

I suppose to further clarify, there's still some coherence requirement there in that crate C can't import the conflicting implementations from both A and B. Which could then perhaps be worked around by adding syntax to spell types along the lines of

    HashMap<i32 + A::impl Hash, V>
Which you could argue is a form of naming implementations, I suppose? I'm not familiar with ML. You could maybe also think of it as a more ergonomic way of doing (more or less) those wrapper types.

In any case, the annotation burden only exists where it's actually needed to enable orphan implementations.

And either way, multiple different impls can safely coexist within the overall set of code that's linked together, with everything being statically checked at compile time.