
Writing my network protocol in Rust - GordonS
https://ayende.com/blog/185665-A/writing-my-network-protocol-in-rust
======
pcwalton
It's interesting to note that the author's better experience with the language
wasn't the result of any one improvement, but rather lots of little
improvements, such as error messages, that overall added up to a better
quality-of-developer-life.

I think Rust development is going to continue to be less focused on big
features and more on small iterative improvements. Rust doesn't need silver
bullets; it needs lots of lead bullets.

~~~
thomasfoster96
From personal experience Rust has the lowest “Google search to error message”
ratio (if that’s a metric) of any programming tool I’ve used. It’s genuinely a
delight to use after having to deal with error messages from various
JavaScript tools, Python packages, and C/C++ build tools.

~~~
inferiorhuman
That all depends on how deep into macro territory you get. My experience has
been that serde-derive and diesel.rs give absolutely arcane error messages.
There are a lot of things that rust at least tries to get right, and that
helps a lot.

That said, even with all the nagging faults I find that rust development feels
more productive than lots of other languages. A large part of that is the
tools, sure, but the other major part is the rust community itself.

~~~
thomasfoster96
It sounds like I probably haven’t gone deep enough into macro territory then.

Still, when having to do things with JS/Python/C++ I’ve wasted many afternoons
down the rabbit hole of trying to glean information from Github Issues,
stackoverflow answers, Twitter threads and obscure forum threads — usually to
find the problem (and fix) I ran into was so trivial it could have been a
single line in an error message. (I feel like a lot of JS tools - particularly
Webpack, Jest and Babel - have regressed a fair bit recently in this regard.
Python just fails silently (or bizarrely) too often and C/C++ compiler error
messages are often less readable than the code itself.)

~~~
inferiorhuman
IIRC rust was designed from the get go to be user friendly. That's why you
have things like intelligible error messages and rls. The rust community, as
well, plays a huge part in how easy it can be to track down answers. But try
debugging a nom parser sometime. Your eyes will bleed.

OTOH the contrast to Javascript is pretty stark. As much as I've got plenty of
complaints about the language itself, the community really a detriment. Things
like Electron and Node actively shun cross-platform compatibility. Tools like
webpack tend to attract cargo cultists. It seems there's a lot of wizardry and
hair pulling involved anytime I touch JS.

C/C++ though has gotten a lot better with the advent of clang.

------
ajross
OK, gotta jump in here and ask the dumb question. What's the deal with this
thing:

    
    
        lazy_static! {
            static ref msg_break : TwoWaySearcher<'static> = {
                TwoWaySearcher::new("\r\n\r\n".as_bytes())
            };
        }
    

AFAICT all the code is doing is parsing the input on a double newline (e.g.
the equivalent of strstr(input, "\r\n")). And this five-line expression is
defining the equivalent of the "\r\n" literal.

What is it that requires that mess? I mean, I get that sometimes typesafety
requires some loss of concision, but...

~~~
est31
The lazy_static macro (provided by a third party crate) allows you to create
static (global, basically singleton pattern) variables that get initialized on
first use and then are being reused over and over again.

The "lazy ref" is part of that macro's syntax. "msg_break" is the name of the
static variable. Then, in Rust, all static things must have type annotations.
In this case, it's the "TwoWaySearcher<'static>". The
"TwoWaySearcher::new("\r\n\r\n".as_bytes())" is the initializer code that's
being only called once. The as_bytes function is solely a type casting
operation to convert from a str for which the typesystem guarantees that it's
utf-8 formatted to a byte slice that just represents arbitrary data.

~~~
ajross
Actually I sort of knew all that (though it was the first time I'd seen
lazy_static! and had to infer it from context).

The question was more about "why"? Again in C the equivalent is literally a
string literal. There's really no easier way to express "double newline" in
Rust than this thing which requires that the reader parse a "lazy static", a
parametrized type, an explicit type conversion and a library utility? Why not?

~~~
coldtea
> _There 's really no easier way to express "double newline" in Rust than this
> thing which requires that the reader parse a "lazy static", a parametrized
> type, an explicit type conversion and a library utility? Why not?_

The code doesn't express 'double newline'. That would be just the
"\r\n\r\n".as_bytes()

The code lazily initializes an TwoWaySearcher to parse such double newlines.

~~~
steveklabnik
Also note that b”” is nicer than .as_bytes()

------
oaiey
Is not Ayende also a big expert in .NET. I am curious about his current
experience with C# considering the huge improvements regarding memory
management in the 7.x series of C#.

~~~
ayende
I'm still using C# (CoreCLR) for most of my day to day stuff. This posts
series is part of my ongoing efforts to improve my knowledge and skills.

I've talked extensively about performance in CoreCLR and how to approach it.
Several records talks are found here:

[https://ayende.com/blog/tags/performance](https://ayende.com/blog/tags/performance)

~~~
oaiey
I was curious especially on the network protocol stack considering that the
ASP.NET team pushed the CoreCLR and language teams a lot to achieve a good
performance with nice syntax and maintainability.

Thanks Ayende for all your content and contributions.

