David Sankel wrote:
There is an important aspect to this review that I want to call out. A signal is a "vocabulary type" in that it is pervasive through systems and frequently used in public interfaces. One of the most important qualities of a vocabulary type is that there be only one of them.
I just started to follow this review, and sadly I only have experience with Qt signals, so cannot really comment on whether adding a second signal type to Boost is a good or a bad thing. The only argument I can extract from your review is that a signal-type is a vocabulary type, and Boost should only have a single signal type. I am missing the why. In particular, since you then argue
Imagine the confusion if we had one thread-safe shared pointer class and another one optimized for single threaded usage,
But I do not need to imagine anything here. Rust has a thread-safe atomic reference counted pointer (Arc) and a non-thread-safe reference counted pointer (Rc) in its tiny standard library. While I've seen users being confused about lots of aspects of Rust, I've never seen anybody confused about when/how to use Arc or Rc. Both complement very well in practice, and arguably this design is a perfect example of C++'s "don't pay for what you don't use".
or if we had an suite of different variant types with different tradeoffs
Recently Boost.Hana was accepted into Boost, with its own tuple type, such that we now have boost::tuple, boost::fusion::tuple, std::tuple, and boost::hana::tuple... So while I agree that having 4 types to do the same thing can be bad, I would really like to hear why do you think that: - Boost.Signals2 signal type chose the right trade-offs, - the trade-offs chosen by Synapse's signal type are not worth the "cost" of having two different signal types in Boost.