Mozilla Welcomes the Rust Foundation
blog.mozilla.org
blog.mozilla.org
I would have loved to see two competing teams rewrite it, one in C++ and the other in Rust.
Saying that the rewrite is better does nothing to say WHY it's better. Refactored code is almost always radically better, even when it's in the same language, for reasons that might be insulting to explain on HN.
Point is, this is not an apples-to-apples comparison.
(I'm not arguing Rust isn't better. Nor that cutting your code base nearly in half isn't impressive. Simply that this single metric on their part seems like weak sauce.)
"This top-down structure is ripe for parallelism; however, since styling is a complex process, it’s hard to get right. Mozilla made two previous attempts to parallelize its style system in C++, and both of them failed. But Rust’s fearless concurrency has made parallelism practical!"
https://blog.rust-lang.org/2017/11/14/Fearless-Concurrency-I...
[1] https://hacks.mozilla.org/2017/08/inside-a-super-fast-css-en...
WebKit has CSS engine is written in C++. Chromium has one too.
After all, Gecko had a C++ implementation too. Nobody is suggesting that any implementation is literally impossible.
Finally, many games and simulators are written in clearly, clearly sub-"optimal" fashion. Games are about fun; not necessarily about extracting maximal possible performance - and compared to browsers, even to minor players like Firefox, even large games have limited usage and especially limited lifetime usage, and they're likely less sensitive to security issues too. As a result, when a game's usage of of parallelism has a few very unlikely race conditions that might not be a show-stopper - whereas it could be an exploitable flaw in browsers.
All in all, it's extremely plausible that games+sims aren't quite as dramatically impacted by C++'s risks as a browser's styling engine is. It's perhaps no coincidence that the language was pretty much designed for it.
> C++ simply wasn't usable for writing a parallel CSS engine.
That's a stronger claim than that C++ was hard to get right. It's a claim that the language is not up to the task.
I mean, you can implement anything you want in assembly, in theory. In practice, the cost of iteration tends to be high enough that implementing things with somewhat rapidly changing requirements (which includes CSS, to be clear!) pretty much requires a language in which iteration and refactoring can be done more quickly than in assembly.
Maybe the confusion on your part is that you think "CSS" is a static set of requirements, so if you put in enough effort to implement it once you're then done? Unfortunately, that's not how it works in practice.
> When the time cost of getting it right and _keeping_ it right exceeds the amount of time actually available in a day, the result is equivalent to "the language is not up to the task".
Again, this is referring to the particular approach that the Mozilla team took to the problem. If anything, one of the most valid criticisms of C++ is that the API is too large, and it has too many tools to work with at the expense of clarity. C++ allows you to express just about anything, and I do not think the standard of evidence has been met that the problem of writing a CSS engine could not be expressed in C++ in a way which would be both performant and maintainable.
C++ has been used for many complex, high-profile projects which are widely used. There is nothing magical about CSS which creates problems C++ is incapable of solving.
Or you could implement Rust in C++.
As you say, you can do whatever you want in C++. The only question is how much time and effort it would take and whether it's worth it.
I will note that the people who worked on the Firefox style system had plenty of experience working on complex, high-profile C++ projects. Every single one of them that I've talked to agreed that for the specific thing they were doing here Rust allowed much faster development of code with fewer bugs (especially as measured by how many issues the fuzzers found) than their past experience with C++ had been.
If your point is that the claim should be "parallelizing the style system in C++ was impossible within the schedule and manpower constraints Firefox was operating under" rather than the simpler "was impossible" claim, then sure, as a purely logical-statement matter. But in practice there are always schedule and manpower constraints.
Can I prove mathematically that some other team would not have been able to achieve the same results in the same amount of time with C++? No, I can't; such a proof would be quite difficult to construct. I do have the empirical observation that there used to be at least four fairly different modern non-parallel CSS implementations out there written in C++ (Gecko, WebKit, Blink, Edge), and that one of them has disappeared (Edge), one was parallelized in Rust, and the remaining two remain in C++ and non-parallel, even though people generally agree that parallelizing them would be good and so forth.
Maybe it's just that none of the organizations involved are any good at writing C++ code. Maybe it's that doing this in C++ is hard enough that it's not worth the effort. Maybe it's something else. What is your hypothesis on the matter?
So my main issue with this claim is that we are talking about proving the negative. Not to get too pedantic, but the reasoning seems to be:
1. Mozilla tried and failed to build a parallel CSS engine in C++
2. Mozilla succeeded in building a parallel CSS engine in Rust
3. Therefore, it is impossible to implement a parallel CSS engine in C++ (under the constraints Mozilla was under).
This is simply not a valid argument. Evidence that something did not happen is not proof that it could not happen.
There are plenty of claims I would accept:
- The Mozilla team found Rust much better than C++ for solving their problem
- Many of the problems the team was running into with C++ were completely eliminated by the constraints provided by Rust
But saying this problem is impossible to solve in C++ is an extraordinary claim which needs extraordinary evidence. C++ is an extremely flexible and powerful language, to say that no one could ever design a solution to this problem using C++ requires a very limited imagination.
> there used to be at least four fairly different modern non-parallel CSS implementations out there written in C++ (Gecko, WebKit, Blink, Edge), and that one of them has disappeared (Edge), one was parallelized in Rust, and the remaining two remain in C++ and non-parallel, even though people generally agree that parallelizing them would be good and so forth.
This is a very small sample size. If I have to give a hypothesis, I can imagine that having a very large, very mature code base like Firefox would have placed a lot of design constraints on any rewrite of the CSS engine. I can imagine that working within this framework, there may have been many problems related to concurrency and data ownership which ended up eating a lot of time and energy in C++, and the team saw a huge productivity boost categorically eliminating these problems. But I simply do not believe it's the case that it's not possible to decompose the problems a CSS engine has to solve into a set of concurrent data structures and operations, which could be expressible in either Rust or C++.
I'm not sure whether the argument now comes down to "it would have been possible to gain that sort of productivity boost in C++ too, with the right design" or "it would have been possible to implement a new CSS engine without this sort of productivity boost". If it's the former, then you're right that one can't prove a negative. If it's the latter, then I think that's where the "schedule and manpower constraints" come in.
I mean, we can blame the humans all we want, but that won't take us anywhere.
Look at what happened to airplane safety and car safety when we stopped blaming the pilot/driver. Fatalities plummeted.
(If we go pedantic, Vec and other primitives do rely on unsafe, but the point is as an application developer you don't have to write unsafe code yourself.)
Also regarding the standard library, as far as I understand it's not entirely true that it never resorts to unsafe rust. For example, I understand that the standard library makes use of specialization, which remains an unstable feature because of a soundness hole in the implementation.
I think you're misunderstanding the parent comment. The stdlib constantly resorts to unsafe code. Tons of methods like `split_at_mut` and `make_ascii_uppercase` are just safe wrappers around an unsafe one-liner.
Rather, the observation is that _with the benefit of the stdlib and common crates_, most programs have no performance reason to reach for unsafe in regular code. That's true in my experience.
For instance, if you read the rust book, they make references to times you might want to use unsafe:
> Borrowing different parts of a slice is fundamentally okay because the two slices aren’t overlapping, but Rust isn’t smart enough to know this. When we know code is okay, but Rust doesn’t, it’s time to reach for unsafe code.
I just looked at the code of a pretty heavily optimized program I've been working on for a few months, I have exactly one instance of unsafe in the code:
pub const GPIO_ID: StreamId = StreamId(unsafe { NonZeroU16::new_unchecked(0xf610) });
I need the unsafe because at the moment the language is not smart enough to understand that 0xf610 is obviously non-zero and that I can build a NonZeroU16 from it without fail (at least I don't know how to express this in static expression at the moment). This has no performance implications whatsoever.Back when I was last measuring this, stylo's single-thread performance was comparable to Chrome's or a bit faster in some cases. Parallelized performance was much better.
That said, actual hardware in the wild has a surprisingly low level of hardware parallelism in practice. https://data.firefox.com/dashboard/hardware shows that for the Firefox user base as of end of Jan 2021 54% of users had 2 cores and 34% had 4 cores.
True, but that's probably about to change soon. Look at the ARM stuff about to enter the arena.
I wouldn't bet on us using just 2-4 cores 10 years from now. And we need to plan for that.
Because software doesn't really need many cores, no need to create CPUs with many, many cores.
I imagine the cycle's going to break at some point, after all we can only ignore having many cores for so long. Especially that now even mobile devices routinely have at least 4 cores.
As you note, the modal number of cores on mobile has been 4-6 for a while now.
The link you posted just indicates that Firefox rendered the page faster than Chrome; did it render it _wrong_?
One other note: the linked issue here is layout, not the CSS system per se; this part is not parallelized in Gecko and is still in C++, not in Rust.
Here's a random example: https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Rust is pretty damn close to the fastest C++ version without any unsafe (but using a bunch of generic libraries which may have unsafe code, to be perfectly fair).
Note that the winning C++ entry is also vastly more complex code and I wouldn't want to have to maintain that.
The n-body benchmark is even more in Rust's favour: https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Here Rust wins the benchmark without unsafe or non-std dependencies. I also find the code very readable and natural looking.
Disclaimer: I love Rust so much that I wish that I could marry it, I'm obviously thoroughly biased.
I think it can be said that Mozilla was able to use Rust to achieve what they failed to with achieve with C++. It's not justified to claim that C++ is/was not suitable for this purpose.
C++ offers direct, low-level control over memory, and C++ can be used to implement anything which can be implemented in Rust. Maybe Rust has certain advantages which made this problem a lot easier to solve for Mozilla, and I'm certainly happy to have Rust in the language landscape, but another team with other processes may have been able to use C++ to achieve similar goals.
It is entirely possible that the best developers on this planet using the best tools and methodologies, processes, whatever, are just not smart enough to do some things.
Considering how many things we have achieved, we should just acknowledged this human attribute: imperfection.
If our tools require us to be perfect, maybe they're just not good tools for some goals.
I'd be shocked if Mozilla didn't have some of the best C++ programmers on the planet, and if they failed a few times, that's a pretty strong argument against C++.
Who knows, maybe they'll be proven wrong and another team working purely in C++ will achieve goals such as theirs. I wouldn't bet on it (though C++ is evolving so who knows how C++ will look like in 20-30 years, never say never).
Looking at their browser, I wouldn't.
> if they failed a few times, that's a pretty strong argument against C++.
Well, they're migrating (at least part of) the codebase to Rust, in a lot of places because of security. Make your own conclusion, I guess?
You could say the same thing about assembly programming or some language that uses GOTOs instead of structured control constructs ... or Brainfuck. Given infinite time and resources, you can implement anything in any language.
Claims about this or that language being unsuitable for a problem aren't really about stuff like Turing completeness, it's more about practical software engineering problems (e.g. does the language provide the right kind of support to the developers allow them to implement the required functionality in a reasonable amount of time with a reasonably small amount of bugs with the budget available).
I think this a reduction of the argument to the point of absurdity. C++ and Rust are certainly much more similar in terms of form and capability than C++ and brainfuck.
> Claims about this or that language being unsuitable for a problem aren't really about stuff like Turing completeness, it's more about practical software engineering problems (e.g. does the language provide the right kind of support to the developers allow them to implement the required functionality in a reasonable amount of time with a reasonably small amount of bugs with the budget available).
I agree. C++ may very well have been unsuitable for Mozilla at the time they adopted Rust. What I take issue with is the general claim that C++ is not suitable for a parallel CSS engine at all. This is a very strong claim, and I do not believe one team coming to this conclusion for them is enough evidence to conclude this in general.
From the point of view of somebody creating a highly interdependent parallel system, no, it's the other way around. On the features that matter to parallel systems, C++ is much closer to brainfuck than it's to Rust.
I know very little about rust, so take this with a grain of salt. It's possible that writing the CSS engine in C++ would require too many custom classes, containers, and build tools outside of the STL than equivalent code in Rust. For example, fast mutexes and mutex safety are not a standard part of C++ but vital to fast parallel C++ code, and the semantics of mutexes are thus very hard to get right. Static checkers for specific mutex implementations can decrease the risk of deadlocks and races but these are additions to C++. If rust provides primitive mutexes with static checking for correctness or other language features (maybe refcell or similar) then it might be worth using rust to stay within the standard language features instead of building add-ons for C++.
You could in theory write the CSS engine in assembly too. A theoretical team, somewhere, could probably manage it. But given better options, it is not a reasonable thing to do.
If they can't pull it off with C++, I don't care who can, C++ is not the right tool for the job and you can file writing such a thing in it as an esoteric programming challenge, together with template Tetris.
1. https://www.openhub.net/p/firefox/analyses/latest/languages_...
- how does the performance of those fare against Stylo?
- the developer of Chrome is so insanely rich that only a tiny tiny fraction of their budgets in practice finance all of Firefox.
Summary: Mozilla manages to make an equally good or better CSS engine with a lower budget?
(I admit Google might be running the Chrome team on a shoestring but my bet is they don't as coming in a position were they can kill ad blocking really would be a fantastic strategic advantage for them and would be worth billions a year.)
The second is the claim I would dispute. The former may be true.
If you want to dispute the claims, do the research, otherwise it's just your opinion against the actual implementation that is shipping to millions of devices.
I'm not arguing that Rust was not the best choice here for Mozilla. I personally would also rather work with Rust than C++ in almost all cases. But to claim that C++ is not usable to solve this problem, based on the fact that Mozilla decided to use Rust instead is not a sound argument.
Can, in practice, a team write and maintain a modern CSS engine in pure assembly? In theory yes, in practice I expect the overhead to be massive.
I think the key feature of Rust for such an application is "fearless concurrency". Writing concurrent code in C or C++ feels like walking a tightrope, in Rust I know that I can lean on the compiler to tell me when I'm doing something wrong. Sure, you can still have data races, but in my experience they're generally pretty simple to debug when they happen because the type system and borrow checker force you to have very explicit data dependency graphs.
I avoid threads like the plague in C and C++, but in Rust I never hesitate if I feel like spawning a worker might improve performance or make the overall architecture simpler.
Assembly offers direct, low-level control over memory, and assembly can be used to implement anything which can be implemented in C++. Maybe C++ has certain advantages which made this problem a lot easier to solve for Mozilla, and I'm certainly happy to have C++ in the language landscape, but another team with other processes may have been able to use assembly to achieve similar goals.
Surely one can code in such style in C++, but it is very unnatural there with a lot of boilerplate, so one just would not consider it typically.
By this measure, anything that is higher level than manually flipping bits in a binary is an inferior language.
If you combined it with a strong theorem proof language.
But then, that's a large part of what Rust is so . . .
Blaming the tool for own failure to do the job isn't all that persuasive.
> C++ simply wasn't usable for writing a parallel CSS engine.
It might be not so much the proof of C++ deficiency as simply another manifestation of mismanagement of the browser development by Mozilla Foundation.
> But Rust’s fearless concurrency has made parallelism practical!"
Because nobody ever wrote concurrent systems in C++?
I would argue it is persuasive if switching to a new tool lead to success. What would be the point of continuing to try the thing that's not working?
The only thing fair is to give one team 6 months (ideally with a couple contractors who are experts to teach them best practices) to try the new thing. Less than 6 months and they are not far enough along the learning curve to make any useful statements. If you want a work done comparison you need to give half your teams (minimum 20 teams, ask a statistician for more details if you want to go lower or could go higher) that 6 months, and then after that give them a year to use the new one in real work, and compare that final year.
You're perfectly right that it would be awful to be pitched against each other in this way.
So I recant my suggestion, but maintain my critique about using lines of code in a single project as somehow validating a language choice. There are too many variables. And, more to the point, the refactored code will almost always be much better, regardless of the language selected.
But I hope most people here don't feel a morale hit when their code gets tossed. Inherently, I understand the desire for one's creative work to live on, but that's essentially incompatible with this industry. And I also have found much joy in turning-down/deleting existing services I've written. My team celebrates these events and it's always fun to give that high-maintenance service a viking funeral.
Using competing teams for this purpose seems like a waste of money to me.
As many others have mentioned though, the real kicker is that they did attempt a rewrite twice in C++ aiming for the features of the rust one; those didn't work out.
You're not wrong! My point was more that we can't take this single data point as proof of Rust's superiority.
That's not how it was done.
Sometimes it is, but it is hardly the rule. New issues will always be introduced. Also, some developers get into an endless cycle of unnecessary refactoring just to use the latest and greatest of some library or framework for no real technical reason.
But the refactor is generally done with the benefit of hindsight of all the things you would have done differently if only you'd known then what you know now.
It's like saying that the second draft or edited manuscript of a novel isn't going to be better than the initial draft. Of course it's better the second time. In theory, you fixed what was wrong with the first one and implemented new and/or improved ideas.
If your refactored code is worse than the original, I feel like you're doing something wrong.
The original vision for Rust sounds a lot like a typed Erlang without the BEAM.
It's not that I don't think the borrow checker etc. stuff is really awesome. I just find the original concept very appealing and incremental. Essentially an OCaml for systems level programming.
A sane C++.
I feel like Rust is making its moves slowly into that territory, but that the memory safety pieces have made it more difficult, even if the long-term payoff is better.
All that said, I'd like a job programming in Rust
Here's what Graydon Hoare had to say about it:
"It's very similar to earlier versions of rust. In terms of actor local GC, language provided scheduling of actors, separated function and async invocation system, mixed structural and nominal types, and an overabundance of language supported reference qualifiers. I think they did a good job at it, certainly much better than I did, but I'd be nervous about the cognitive load of the reference qualifiers (capabilities). See this page for example, or the previous few in the tutorial. We had that sort of cognitive load on variables early on and people basically rejected the language because of it, as well as associated compositionality problems. The many years of design iteration had a lot do to with factoring that space into fewer, more essential and general qualifiers. Slow, tedious, world breaking refactoring work. I hope for pony's sake this doesn't happen to them too -- it looks really nice -- but that's my biggest worry for it."
http://www.reddit.com/r/rust/comments/34rszb/pony_type_and_m...
2. Parallelism. There is currently a python-like lock so that only one thread may run ocaml at a time. There is a long-running project (multicore) to fix this
3. (Opinionated) lack of control of mutability: it is easy to have everything immutable or an object with fields that are always mutable, but you can’t easily have something like rust’s mut, which only sometimes allows mutation. Some changes to this may come with/after algebraic effects which come after multicore, but these are mostly about avoiding atomically where possible rather than making things const.
4. The compiler just isn’t as good as a c++ compiler and it needs to be better to undo a deeper stack of abstractions. I think it’s particularly bad for not really doing monomorphisation. On the other hand, it’s fast.
5. (Opinionated) it isn’t great for writing generic code, but maybe modular implicits will fix that.
That said, it is possible to write fast systems level programs in ocaml (you can be careful and avoid allocation in critical sections, or just have gc because for most systems it doesn’t matter that much. You can split things into multiple processes if necessary.) You could look at mirage for an example of something big and low level written in ocaml.
But GC is really problematic.
Now it's sorted out but I think it crippled the language early on and now it's sandwiched between other "managed" languages with far better adoption and better support on one side (Java/JVM languages, C#, Go) and low level system language with better adoption and no GC on the other (C++/Rust in particular).
While I personally find D interesting and vastly better designed than some of the competition (cough go cough) it's very hard for me to imagine it getting big in the mainstream without some massive industry backing.
I guess the question is, does it really need to be mainstream to be usable? As long as it works for the usecases you need it for, popularity isn't a necessary factor.
I have to say though that D has some issues that prevent it's wider adoption, both historical and current. Some are obvious, such as unnecessary two standard libraries conflict (I missed out on it, but the OOP person in me would have preferred Tango over Phobos).
But I think it is beating C++ at its own race. The C++ weirdness is just... Bureaucratic and verbose.
Rust is clunky at times but even then it is smoother than C++
I'm sure some C++ codebases will outlive everybody posting in this thread.
I don't think the Foundation ever plans to employ so many people to work on the language. Most of the people who left Mozilla now continue to work on Rust at Amazon, Microsoft and Facebook. By no means am I defending Mozilla here, just saying that the Foundation wasn't the solution to employ 10+ engineers working full time on the language.
The developers who have newly joined these companies have years of contributing to the Rust project. I'm 1000% confident that they wouldn't land anything that wouldn't be welcome by all users. For example, one engineer at Amazon is working on making it easier for Amazon engineers to learn the language by improving the error messages. Those improved error messages benefit everyone.
> Importantly, rising CEO pay does not reflect rising value of skills, but rather CEOs’ use of their power to set their own pay.
Source: https://www.epi.org/publication/ceo-compensation-2018/
I find these arguments persuasive.
> You may recall that we expected to be earning revenue in 2019 and 2020 from new subscription products as well as higher revenue from sources outside of search. This did not happen. Our 2019 plan underestimated how long it would take to build and ship new, revenue-generating products. Given that, and all we learned in 2019 about the pace of innovation, we decided to take a more conservative approach to projecting our revenue for 2020. We also agreed to a principle of living within our means, of not spending more than we earn for the foreseeable future.
[NOTE: per the link in the parent comment, "Mozilla's 2019 expenses came to $495.3 million, or almost $5 million more than revenue."]
> This approach is prudent certainly, but challenging practically. In our case, it required difficult decisions with painful results. Regular annual pay increases, bonuses and other costs which increase from year-to-year as well as a continuing need to maintain a separate, substantial innovation fund, meant that we had to look for considerable savings across Mozilla as part of our 2020 planning and budgeting process. This process ultimately led us to the decision to reduce our workforce.
https://techcrunch.com/2020/01/15/mozilla-lays-off-70-as-it-...
[0]: https://cloudblogs.microsoft.com/opensource/2021/02/08/micro...
[1]: https://aws.amazon.com/blogs/opensource/congratulations-rust...
[2]: https://opensource.googleblog.com/2021/02/google-joins-rust-...
https://opensource.com/business/16/2/bright-lines
https://towardsdatascience.com/the-unsung-heroes-of-modern-s...
Something feels strange about the founding members of the Rust foundation. It looks like Rust is going to have a similar structure like the C++ committees or even the Linux Foundation (which Servo is now part of) given how big tech companies seems to have a wide presence in these technologies and these foundations which is fine for usage, but very worrying in terms of having seats at the board with the potential risk for them to drive that technology in their interests and we have no say about this.
I feel these announcements have glossed over this important aspect.
That’s like 4 full time engineers. Not even a 5 a side football team.
So you could certainly get more than 4 engineers on board, plus some project managers etc
In London, >£100k is easy for contractors but I think you'd have to have some managerial responsibilities to get that as a perm (team lead or upwards.) But I may also be moving in the wrong circles...
It's possible, but unusual, for base salaries for individual contributors to be over £100k, especially if you look at both FAANG/adjacent companies and financial firms (both investment banking and at hedge funds). If you include bonuses and stock compensation, those same groups can relatively easily hit £100k.
I'd personally never consider those in salary calculations - been burned too many times. But yeah, I guess if people are getting bonuses and other compensations, it could well boost them over £100k.
Healthcare, vacation time and better work/life compensate that ( for some).
John Carmack @ID_AA_Carmack
https://twitter.com/id_aa_carmack/status/1293227109738061826...
Why no Firefox Foundation?
Wasn't Mozilla already a non-profit Foundation?
On its own, it is a great move for Rust, more independence, but this sounds more like a new title for marketing PR purposes than anything else.. hope i'm wrong, rust needs it
EDIT: what makes posts reach #1 on HN?