Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added default attribute to match arms for specialization in nightly #1

Merged
merged 1 commit into from
Jul 19, 2021

Conversation

akiselev
Copy link

Thank you for the great work on this library! It has made type level programming a lot more tractable.

I've added a #[default] attribute for working with specialization

@jerry73204
Copy link
Owner

Thanks that you take a glance on it! I'd like to understand the status of specialization. Seems the RFC-1210 is merged but the implementation is still in its journey. Does it mean that default impl will be eventually land? If yes, I'm glad to merge this PR.

@akiselev
Copy link
Author

akiselev commented Jul 11, 2021

That's a difficult question to answer. The specialization RFC has been open since 2016 and based on tracking issues marked B-unstable it's the 29th oldest issue still stuck in nightly along with stuff like like LLVM intrinsics, SIMD, and so on. It's well established that the feature as currently implemented is unsound (possible undefined behavior even with zero unsafe code) without a clear path forward and I've got repos from 2018 that still cause the newest compiler to ICE. That said, the min_specialization feature is meant to be a stop gap that allows specialization in the standard library until the soundness holes are figured out or a new design emerges.

Based on my experience, min_specialization is a sign that this feature will happen, but it'll take a while since it probably requires chalk and other implementation details for generic associated types to land. I'm fairly certain of that because async/await took a similar path, stabilizing long before the feature they're implemented on (generators) and enabling unboxed futures in trait return types requires fixing many of the type system issues that specialization has.

There's just too much demand for this feature and it's too powerful, especially with GATs - it just happens to be one of the hardest features to implement. I think it's worth providing nightly features here (at least behind a feature flag) to enable experimentation but I'd hold off on this PR until I've had more time to play with it in my code base (show stopping specialization errors tend to happen at the point of use, not declaration, so you can't know whether a specific design is practical or not until it's too late). At the very least, the way trait bounds are specified on the output (where Self::Output: Trait instead of type Output: Trait) seems to break callsites because Rust can't resolve the trait implementation from the default associated type. Based on the tracking issue for associated type defaults (the 26th oldest), it looks like associated types are the core soundness issue and this PR might be moot. Users might have to specialize traits with concrete functions over the types returned from typ functions, instead of specializing the type level functions themselves.

Side note, have you had a chance to experiment with generic associated types? They landed in nightly in December so its still a very new feature but its critical to async/await and it's a much more mature design (I've had a lot more fun and far fewer compiler ICEs playing with it). They will 100% land in Rust sooner or later and should allow for higher order type level functions, for example (pseudocode, haven't tried implementing this in the typ macro yet, but it works when hand written):

trait Func<T> {
    type Output<U>;
}

typ! {
    fn fmap<t1, t2>(t1: Func, t2: _) {
        Func(t1)(t2)
    }
}

@jerry73204 jerry73204 merged commit b2677fa into jerry73204:master Jul 19, 2021
@jerry73204
Copy link
Owner

I will accept nightly and unstable features that are expected to land, and also the typ itself is experimental.

I look forward to GAT to land and wonder if it works in recursive type construct. I've been experimenting processing type level lists, for example, pytorch-like broadcast operation (doc) on two dimensions. It's challenging to implement in types. Think of a list of compile-time numbers and dynamic runtime numbers. It should be able to put dynamic checking stubs for dynamic numbers, so you get many cases to deal with.

Anyway, feel free to share your mind here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants