Hacker News new | ask | show | jobs
by tialaramex 1460 days ago
Chromium had a few problems, they're public so we can go read the changes made and look at the context.

In a lot of places in Chromium the impedance choices are arbitrary. You have a raw pointer but need a string or vice versa. Ownership isn't the problem, so in Rust you literally just always choose &str for these APIs and pay nothing. A team who design their API taking &String in this situation get the same treatment as a team who name all their types Data1, Data2, Data3 and so on. Somebody senior fetches the water spray, "No. Bad programmer".

You might be outraged, surely C++ programmers also never get this wrong. But nope, happens all the time as Chromium illustrates.

Added: One cause that shows up in my review is this:

C++ strings know how long they are. The raw pointer does not. As a result if we have lots of people asking if their thing is "some text" it's tempting to demand they give us a string, since if the string's length isn't 9 we don't need to look at the text itself. It's an optimisation! Rust's &str knows how long it is.

1 comments

Again I’m failing to see the distinction. Why did that team need a string? Presumably it’s mutating right? &mut str would let you mutate the existing characters (similar to char) but it doesn’t give you permission to resize (since doing so obviously might involve a reallocation and change underlying pointers referenced elsewhere).

> A team who design their API taking &String in this situation get the same treatment as a team who name all their types Data1, Data2, Data3 and so on. Somebody senior fetches the water spray, "No. Bad programmer". You might be outraged, surely C++ programmers also never get this wrong. But nope, happens all the time as Chromium illustrates.

So the thrust of your claim is that Rust programmers are better. The more generous interpretation I’ll read here is that Rust has stronger conventions here. Even still. I don’t see it. The problems are still the same. I think there’s a hyper focusing on ownership when it has nothing to do here. In c++ Const Char (and now string_view) == &str. Chrome developers were going from &str to String and back many times. If Rust had some way to convert &mut str to String without a copy if none was needed, then I think that might apply.

>Again I’m failing to see the distinction. Why did that team need a string? Presumably it’s mutating right?

As a Rust programmer this is what I'd expect, because that's what alloc::string::String is for but this is not how std::string is used in C++ & especially not how it was used at that time

So I spent some more time reading. Beyond signifying ownership std::string has other properties that the raw pointer char * does not have which influence the C++ programmer and especially the enthusiastic but perhaps less experienced C++ programmer

1. It's a real C++ type whereas char * is left over from C

2. Unlike char * the std::string remembers the length of the string which also speeds up equality comparison (we know "classification" != "class" from the length before we even look at the text data)

3. std::string has a "Small String Optimisation" which will be emphasised repeatedly to you by C++ gurus. This means small local strings don't need heap space which is good. So... you should use std::string?

Now. If we compare &str and alloc::string::String:

1. Both Rust types, not left over from some prior language

2. Both know how long they are

3. Neither has "Small string optimisation". You can do this trick (oh boy and how) in Rust, but Rust's standard library intentionally does not provide it and nobody's public APIs expose such a thing.

> &mut str would let you mutate the existing characters (similar to char) but it doesn’t give you permission to resize (since doing so obviously might involve a reallocation and change underlying pointers referenced elsewhere).

Yes it would, and this exists but I've rarely seen it put to any use.

> The more generous interpretation I’ll read here is that Rust has stronger conventions here.

Ultimately yes, the conventions are stronger, a cultural difference. You can go look for yourself, at both the sprawling vastness of public Rust library and Chromium's own APIs in that era which often take string despite having no interest in ownership.

Chromium has a map (of configuration parameters) inside it, in which the keys are std::string. If you understand this as an owning object for mutation that sounds insane but if you just think it's a convenient object that knows how long the text is and keeps shorter text out of the heap it's awesome. Right?

Of course, you can't just compare a char * to a std::string, the map has no idea that would be possible, so you make a std::string from your char * and compare that. Don't worry there are only a few dozen configuration parameters to check, what do you mean this hash lookup now incurs a heap allocation ?