aatxe / irc

the irc crate – usable, async IRC for Rust
Mozilla Public License 2.0
530 stars 97 forks source link

Zero-cost abstractions #107

Closed SoniEx2 closed 6 years ago

SoniEx2 commented 6 years ago

We have zero-cost abstractions. The whole lib should be built on zero-cost abstractions. This means IRCv3 support should not be part of the core crate, but a separate crate. Rather than using features, enabling IRCv3 should be done by including the IRCv3 crate as a replacement, and so on.

Zero-cost abstractions are amazing and they should be used everywhere. Especially when it means you can remain apolitical and not side with either pro-IRCv3 or anti-IRCv3 groups.

retep998 commented 6 years ago

What would you say is the current non-zero cost of having IRCv3 support built in by default? In what ways does it currently detract from the efficiency you expect?

SoniEx2 commented 6 years ago

It's not the cost, it's the abstraction.

You currently have IRCv3 built-in, and part of having IRCv3 built-in is that you have leaky abstractions for it, so even when you're not using IRCv3 you still have all the IRCv3 crap pulled in. It's also nowhere near as flexible as having IRCv3 an external crate independent of the internal structure of the library. (But please, don't put IRCv3 stuff in the public API of the core crate, because that's not really flexible that's just a feature flag disguised as a crate.)

retep998 commented 6 years ago

If it's not about the cost, then why do you bother mentioning "zero-cost" so prominently?

What is it about IRCv3 that causes you to be so massively concerned about having support for it by default? Compile times definitely can't be your concern as IRCv3 support doesn't require any additional dependencies. Do you simply oppose the IRCv3 standard and want it shunned to a separate crate where it can be avoided like the plague? (You do refer to IRCv3 as "crap")

Maybe you could give some specific examples of how IRCv3 support has a negative impact on the library. For an example of a case where moving IRCv3 support to an external crate would be a bad idea, just look at the Command and Message types. Making them "flexible" types that can be extended with support for IRCv3 tags through an external crate would be significantly more complicated than the current solution and would probably have a negative impact on performance compared to the current solution.

SoniEx2 commented 6 years ago

That's why the IRCv3 crate should follow the principles of zero-cost abstractions. The main crate provides traits for messages and things, the IRCv3 crate takes any T: Message, another extension crate takes any T: Message, and so on, and they can define their own trait types like Ircv3Message or w/e if they need to. Note the use of generics - this is what makes them zero-cost.

It's mainly about abstractions, not cost, altho cost is a factor I'm taking into account here.

If you can have IRCv3 as a completely external crate like that, then so can any other IRC extension. Formatting? Could be a crate. CTCP? Also a crate. And so on.

Not only does it make the library significantly more extensible, it also reduces maintenance cost, as you can defer IRCv3, formatting, etc support to someone else (and in the case of IRCv3, even multiple separate crates).

aatxe commented 6 years ago

While I agree that more abstraction would make the library more extensible, I don't believe that this comes for free from the perspective of a library consumer. More abstraction means more details that need to be understood to use the library, even if the runtime impact is zero. The extensible API design is also non-obvious to me. While some details (like sending messages of various types) might be intuitive, others (like receiving messages of various types) are less so.

If you're interested in pursuing a more abstract design, I encourage you to experiment with it. You can fork this library and try to work it out, or start your own from scratch if you're so inclined. I'd be happy to answer any questions you might have, or offer help in the process.

SoniEx2 commented 6 years ago

Hmm... We (myself included) should probably work the terminology a bit better... How about:

So you could have a trait IrcCommand, for example, which provides just a very basic IRC command.

An IRC connection could then have an IrcCommand as an associated type. Then you could have SimpleIrcConnection::new() and Ircv3Connection::new(), which wrap the whole thing for you.

If a library consumer wants just bare IRC support, with no IRCv3, they'll do SimpleIrcConnection::new() and be done with it. This would indeed be very basic, with no support for formatting or CTCPs (no /me's, even!).

If a library consumer wants IRCv3, they'd load up the IRCv3 crate, and use Ircv3Connection::new(). This would still support bare IRC, with no IRCv3, but it would also support formatting (perhaps through another crate) and maybe CTCP (altho IRCv3 doesn't really like CTCP), and when supported by the server it would automatically enable IRCv3 features.

If a library consumer wants more features, they could wrap them themselves, or hook into one of those crates - hopefully they'd provide some primitives to help with it. At least the IRCv3 crate would probably be designed this same way, to deal with additional extensions (twitch emotes could be third-party, for example).

This keeps things simple for library consumers, and allows a significant amount of extensibility - the IRCv3 connection would handle message tags, for example, and then pass the post-processed commands onto the normal IRC handling.

aatxe commented 6 years ago

Seeing as this issue suggests rewriting the entire library from scratch using a highly generic design and the original poster is working on their own library, I'm going to close this issue.

SoniEx2 commented 6 years ago

Are those bad goals? It's fun to see how implementations of the same idea differ.

aatxe commented 6 years ago

Absolutely not! It's just out of scope for this crate (since it's a proposal for another crate). I'm very interested in seeing where your library goes, and as I mentioned before, am happy to answer questions or help where possible.