Live data from Hacker News

Implications of Rewriting a Browser Component in Rust

hacks.mozilla.org

141–150 of 279 posts

Re: Implications of Rewriting a Browser Component in Rust

#141

Earlier quoted context omitted.

It’s probably a combination of both things, but “I tried rust, struggled, quit, came back months or years later and now I have no idea why I thought it was so hard” is certainly a recurring pattern we’ve seen. Glad it’s working for you now!

Because people underestimate the amount of effort needed to learn a new language at first?

For real Beginners to programming Rust can be hard, because concepts like pointers are hard in most languages that use them.

For Programmers that try Rust out Rust can be hard because they are stubornly trying to program Rust as if it were Python/Java/C/C++/Foo – but it isn't.

Rust as a language makes certain types of approaches (or anti patterns) nearly impossible. In the beginning it happens quite often that after a day of struggle you will erase a Rube-Goldberg-Machine that does something simple and replace it with the right line of code that does exactly the same while beeing way more extensible.

If you find yourself building more and more elaborate structures just to get something very simple done, the problem is very likely your approach (e.g. trying to implement a OOP structure instead of solving the problem) – at least that is what happend to me a lot.

Rust's borrowing and ownership concepts, as well as traits and generics make it extremely powerful, but these concepts lend themselves better to certain ways of structuring code than to others. Learning something is in my opinion always about allowing something to change your perspective. If you are not allowing the thing you are learning to change you, chances are that you are not learning, but judging.

Re: Implications of Rewriting a Browser Component in Rust

#142

Earlier quoted context omitted.

That’s one aspect of the errors that are avoided, but there are many others too - some of which aren’t solved by other languages. Go, for example, will happily nail through all of your obviously null pointers with gay abandon. The Rust ownership model prevents other classes of bugs. It’s not a panacea—and to be blunt, I find Rust more work than it is worth for the sort of projects I typically work on. But any tools w…

I was responding to the issue I quoted, which really is just a matter of using a programming language with static typing. :) > some of which aren’t solved by other languages You only mentioned null pointers, so I will go with that. In Ada, you can have access types (pointers) that are guaranteed to not be null, and accessibility rules of Ada prevent dangling references to declared objects or data that no longer exist…

I will give you a few examples. My knowledge of Ada is insufficient, so I'll let you tell me whether Ada can solve that without using an external prover (note: being able to use an external prover is great and I haven't seen this done in Rust yet :) – but that's not the topic at hand).

1/ Consider a file `f` (or a socket, etc.). Using the standard library, Rust will statically ensure that, once the file is closed, you cannot attempt to, say, read from it. This is nothing special to files, just an aspect of the borrow checker.

2/ Consider a communication protocol. You need to send a message `HLO`, expect a message `ACK`, then send something else, etc. It is pretty easy to design your objects such that the operations of sending the message, receiving the message, etc. will change the type of your protocol object, ensuring statically that you never send/expect a message that you're not supposed to send in the current state.

If you're curious, I wrote a blurb last year on the topic: https://yoric.github.io/post/rust-typestate/

3/ I quickly googled "Ada spark phantom types" and didn't find anything. Does Ada support phantom types?

Re: Implications of Rewriting a Browser Component in Rust

#143

Earlier quoted context omitted.

But what would you put in such an ABI beyond what's in the C ABI? Beyond basic data types, struct defintions, and function definitions, languages begin to wildly diverge almost immediately.

Multiple return values. Ownership annotations. SIMD type support. String charset information. More challenging would be to include stuff like allocation management (how to free a pointer when it's done), GC integration, function boxing, iterator/generator support. Vtables and cross-language inheritance is interesting but difficult. One point of clarity: this would be an FFI ABI, not necessarily expecting that most da…

> Vtables and cross-language inheritance is interesting but difficult.

Windows' COM "solved" that problem. For example see C++/WinRT[0] for a modern C++ interface to COM. Or the C# .NET equivalents.

[0] https://github.com/Microsoft/cppwinrt

Re: Implications of Rewriting a Browser Component in Rust

#144
post #72

This is in tune with my own experience using Rust in production: it can stop you from doing certain classes of mistakes, but it won't stop you from doing stupid things. But the idea that I don't have to think about certain classes of problems allows me to give these stupid things more focus, which is surprisingly refreshing. The predictable nature of Rust was so refreshing for me that I ended up using it even for sma…

> before but soon got annoyed with obvious errors that would only show up once you run a program. From what I gather you are comparing static vs dynamic typing, and I agree. I do not use Python because I prefer a subset of errors caught at compile-time. However, it is silly to make it sound like that this is somehow limited to Rust. You could just as well have used Go or OCaml and feel "refreshed" because obvious err…

Sorry if I angered you. I never claimed that Rust was the only language that has these properties.

My experience was is: I have never seen a language/environment where these rules were so well thought out, so well communicated and so well enforced. The package managment works like a charm, the module system (since edition 2018) is the best I have seen etc.

These are all subjective – I am a film/philosophy student who codes and I never received any formal education on any CS related topic. I was speaking about why Rust feels sound to me. Good chances Haskell will look sound to me too, very good chance I might check out more CS topics. No hard feelings please.

Re: Implications of Rewriting a Browser Component in Rust

#145
post #60

One of the major hurdles in rewriting parts of C++ projects in Rust is that the interop surface between both languages is C. The necessary interface layer has created more bugs and work than the conversion saved. I'd really like to see more high-level interoperability between the two languages in the future, although C++ is a pretty fast-moving target at this point, with all the changes in C++20.

This was my experience when I was at Mozilla converting a part of Firefox to Rust. It also feels like a lot of Rust's safety guarantees go out the window when you are using the C FFI to talk between C++ and Rust. I'm not sure how bad it actually is in practice (vs just writing the whole thing in C++).

Re: Implications of Rewriting a Browser Component in Rust

#146
post #55
post #4

It's nice to see a balanced, real world, case study including 'these things are fixed by Rust', 'these are problems that don't occur in idiomatic Rust', and 'these are problems that Rust can't help you with'. I'm a big fan of Rust, but the one sided 'Rust makes all the problems go away' articles don't provide any value.

Overall, it did a decent job of being balanced, but I don’t buy the memory overflow example at all. For one thing, idiomatic C++ bounds checks by default. You need to use at(). If you don’t like typing at(), you can implement an array type that always bounds checks fairly easily. On that note, the vulnerable c++ code should be using accessors, not indexing to access the oddly packed and laid out array. Even the fixed…

I've heard these "idiomatic C++" and "improved data structures" arguments a few times and as a C++ developer, I'm a bit skeptical. Does anybody know of any non-toy C++ projects that actually demonstrate such a high-level of reliable use of C++?

If so, how much do they rely on the developers being ideal programmers, who know intimately the intricacies of C++ and how to avoid ending up in UB-land?

Re: Implications of Rewriting a Browser Component in Rust

#147

Earlier quoted context omitted.

> For one thing, idiomatic C++ bounds checks by default. You need to use at(). Sounds like it doesn't check by default then. It checks if you remember to check using the more verbose bounds-checking method. Not unlike the issues with subscripting std::map.

I have some experience in C++, and I am familiar enough with the standard library to remember that operator[] doesn't check bounds while the at member function does. I would assume that the Firefox C++ programmers know this as well. However, maybe I'm wrong or have too much faith? Or, maybe, the programmer was aware that operator[] didn't perform bounds checking, but opted to use it for some reason? A good way to dis…

The relevant code in fact uses a non-STL array container. Unfortunately, the performance of the STL containers is fairly unreliable across C++ standard library implementations and can be very poor in some cases. That makes them harder than it should be to use in code where you need to understand the performance characteristics of your data structures.

Re: Implications of Rewriting a Browser Component in Rust

#148
post #7
post #4

It's nice to see a balanced, real world, case study including 'these things are fixed by Rust', 'these are problems that don't occur in idiomatic Rust', and 'these are problems that Rust can't help you with'. I'm a big fan of Rust, but the one sided 'Rust makes all the problems go away' articles don't provide any value.

It also highlights an example of a security bug introduced during rewriting; highlighting that rewriting any significantly large piece of software is bound to introduce bugs.

Not just introducing new bugs but reintroducing old bugs which were publicly documented and/or previously exploited. Which you could argue are worse as it’s a lower barrier for detection by attackers, but also on the otherhand by the team/community.

Also of note was that there was already an automated test for one of the high priority bugs that got reintroduced but the that particular tests was turned off.

Re: Implications of Rewriting a Browser Component in Rust

#149

Earlier quoted context omitted.

The alternative tends to be to propagate the error upwards using the `?` operator, up to some point where it makes sense to handle errors

Aka exceptions. Yes, chaps, that Result type is all but isomorphic with checked exceptions, Java-style.

Semantically, returning a sum type like Result absolutely is the same thing as exceptions (ie, it's the exception monad).

However, there's one very important language design difference between this and Java-styled checked exceptions: using sum type gives you effect polymorphism for free. This means you can write (say) a map function which says it has precisely the same exception type of its argument function, using the same machinery you're using for generics everywhere else.

This is a big from the usability side, since AFAICT it was the lack of effect polymorphism that turned people off of Java-style checked exceptions. From a language implementation standpoint, it's also nice not to have to implement type inference twice, once for return values and once for exceptions. :)

Re: Implications of Rewriting a Browser Component in Rust

#150

Earlier quoted context omitted.

Agreed but Python lazy-loads & parses files as packages are imported. By convention these are all at file scope and at the top of the files, so it's often confined to an initialization phase. But...sometimes developers use clever fallback behavior by catching ImportError. So the scenario described is possible to escape simple tests, I suppose.

Doesn’t the print raise a SyntaxError not ImportError?

Yes, sorry if that was confusing -- perhaps I shouldn't have brought up ImportError. The point was that uncovering SyntaxError could possibly be as challenging as other feature tests.

    try:
        import collections
    except ImportError:
        # fallback impl of collections:
        import something_that_uses_print_statement
Post reply on HN