4 releases

0.1.3 Dec 27, 2021
0.1.2 Dec 27, 2021
0.1.1 Jul 11, 2019
0.1.0 May 10, 2019

#792 in Rust patterns

Download history 3/week @ 2024-09-23 7/week @ 2024-09-30 116/week @ 2024-10-07 4/week @ 2024-10-21

121 downloads per month
Used in 2 crates

MIT/Apache

30KB
211 lines

Syllogism

Utilities to allow for some specialization using stable Rust.

Specialization is a feature for the rust programming language that is being developed.

Features

This crate provides two techniques for specialization:

  • Using the IsNot trait. This can be used when the data-type that you want to specialize for is a concrete type.
  • Using the Specialize trait. This can be used when the data-type that you want to specialize for is a type parameter.

Both techniques require a huge amount of boilerplate. The syllogism-macro crate provides some procedural macros that can generate this boilerplate for you.

Note that this crate can only be used for certain types of specialization, see the examples below.

Status of the project

syllogism and syllogism-macro are experimental crates and not really actively maintained.

Specialization was mentioned in the 2019 roadmap. The syllogism and the syllogism-macro crates were meant to be used in a transition period when specialization is not yet available in stable Rust. In August 2021, specialization is not yet stabilized.

The motivation for the syllogism crate was to allow for a certain design in another crate. However, it turned out that this design was overly complicated and that a much better and more simple design did not need specialization. Also the ruma crate changed the design so that specialization is not needed (podcast, 41'30'').

Given these lessons learned and the status of the specialization feature in August 2021, our recommendation is the following:

  1. If you want to use specialization to allow for a certain design, check if you can come up with a more simple design that does not require specialization. Maybe you're trying to abstract away too much? Specialization is a common feature in many OO languages, but it's well known that in general, OO design patterns do not translate very well to Rust. We recommend to try to rethink your problem, maybe involving others in design discussions.

  2. If you want to use specialization for performance reasons, benchmark the performance gain you would get. Maybe it's not worth the effort.

  3. You can use syllogism and syllogism-macro to validate your design or to benchmark the performance, but we don't recommend to consider it to be a structural solution.

  4. There is no guarantee that once specialization is available in stable Rust, the IsNot and Specialize traits can be implemented without boilerplate and without using the macros from the syllogism-macro crate. For this reason, if you use syllogism or syllogism-macro, we recommend to not only depend on the syllogism and syllogism-macro crates, but also have a feature in your crate that you can use to conditionally compile your crate with syllogism and syllogism-macro when using stable Rust and with the specialization feature flag turned on when compiling with nightly Rust.

Examples

Using the IsNot trait:

// One special implementation:
impl GenericTrait<SpecialDataType1> for MyStruct {
    // ...
}
// Another special implementation:
impl GenericTrait<SpecialDataType2> for MyStruct {
    // ...
}
// The generic implementation.
impl<T> GenericTrait<T> for MyStruct
where T: IsNot<SpecialDataType1> + IsNot<SpecialDataType2>{
    // ...
}

Using the Specialize trait:

impl<T> GenericTrait<T> for MyStruct<T>
where T: Specialize<SpecialDataType> {
    fn some_method(&self, param: T) {
        match param.specialize() {
            Distinction::Special(special) => {
                // The special implementation.
            },
            Distinction::Generic(generic) => {
                // The generic implementation.
            }
        }
    }
}

Contributing

We welcome contributions, both in the form of issues and in the form of merge requests. Before opening a merge request, please open an issue first so that you know whether a subsequent merge request would likely be approved.

License

This crate is distributed under the terms of the MIT license or the Apache License (Version 2.0), at your choice. For the application of the MIT license, the examples included in the doc comments are not considered "substantial portions of this Software".

No runtime deps