Rust went from side project to world’s fastest growing language(technologyreview.com)
technologyreview.com
Rust went from side project to world’s fastest growing language
https://www.technologyreview.com/2023/02/14/1067869/rust-worlds-fastest-growing-programming-language/
297 comments
im so tired of non-substance rust content on hn. i dont want to know THAT it is written in rust (shocking, i know!) I want to know WHAT made it better to be in rust rather than x. I'd read the shit out of an article about that. its starting to become a meme cheatcode, just add "in rust!" to the end of your post title and you'll get a baseline starter pack of hn votes
I was going to add a boring "me too" reply. But then I re-wrote it in Rust and it's now 10 times more insightful!
I am going to have to borrow this comment.
The constant Rust spam on the front page makes me think that there may be some sort of pro-rust bot that upvotes them. There probably isn't, just a lot of enthusiasm, but it's tiring.
However, it has also convinced me that Rust isn't faster than C++ in practical applications, thanks to the number of "we moved our C++ codebase to Rust" blog posts that have 0 benchmarks. You can practically guarantee that if their code had gotten faster, they would have said something about it. That has dulled my enthusiasm for the language significantly.
Also, it is humorous to me to see blog posts that say, "[Rust feature that causes inconvenience] enables compilers to do [compiler optimization that C++ compilers already do]."
However, it has also convinced me that Rust isn't faster than C++ in practical applications, thanks to the number of "we moved our C++ codebase to Rust" blog posts that have 0 benchmarks. You can practically guarantee that if their code had gotten faster, they would have said something about it. That has dulled my enthusiasm for the language significantly.
Also, it is humorous to me to see blog posts that say, "[Rust feature that causes inconvenience] enables compilers to do [compiler optimization that C++ compilers already do]."
> The constant Rust spam on the front page makes me think that there may be some sort of pro-rust bot that upvotes them. There probably isn't, just a lot of enthusiasm, but it's tiring.
I get it; we all have our annoyances. Personally, the above kind of comment is tiring. Complaints about what makes the HN front page seem like a waste of energy. How can we contribute to moving the conversation forward? By "forward" I mean learning from each other, sharing ideas, and other constructive goals.
P.S. If you don't want to see [keyword] in HN, there are probably browser extensions that can help you.
I get it; we all have our annoyances. Personally, the above kind of comment is tiring. Complaints about what makes the HN front page seem like a waste of energy. How can we contribute to moving the conversation forward? By "forward" I mean learning from each other, sharing ideas, and other constructive goals.
P.S. If you don't want to see [keyword] in HN, there are probably browser extensions that can help you.
The problem is that I am interested in Rust's development and I do want to see the Rust keyword, when the content is substantive. For example, there is another front page post right now about Rust and Haskell, which is an interesting commentary.
The complaint is about the input not the output.
>>> pclmulqdq: The constant Rust spam on the front page makes me think that there may be some sort of pro-rust bot that upvotes them. There probably isn't, just a lot of enthusiasm, but it's tiring.
>> xpe: ... Personally, the above kind of comment is tiring. Complaints about what makes the HN front page seem like a waste of energy. ...
> 0xdeadbeefbabe: The complaint is about the input not the output.
Explain, please. What is the input? The output?
>> xpe: ... Personally, the above kind of comment is tiring. Complaints about what makes the HN front page seem like a waste of energy. ...
> 0xdeadbeefbabe: The complaint is about the input not the output.
Explain, please. What is the input? The output?
As far as I can tell, the input is the low-effort "I like Rust but have no insight" blogs. The output is their appearance on the front page of this website.
>Also, it is humorous to me to see blog posts that say, "[Rust feature that causes inconvenience] enables compilers to do [compiler optimization that C++ compilers already do]."
What? You can't safely do strict aliasing in C++ and even if you did, it was broken anyway to the point where the Rust compiler had to disable it because of LLVM bugs.
https://github.com/rust-lang/rust/issues/54878#issuecomment-...
https://news.ycombinator.com/item?id=25624538
What? You can't safely do strict aliasing in C++ and even if you did, it was broken anyway to the point where the Rust compiler had to disable it because of LLVM bugs.
https://github.com/rust-lang/rust/issues/54878#issuecomment-...
https://news.ycombinator.com/item?id=25624538
Strict aliasing maps to TBAA in LLVM; the buggy feature is noalias, which corresponds to C's restrict.
The restrict keyword historically has meant "I know these pointers are different, please optimize as though they are." It had nothing to do with correctness. It is quite tricky to check for correctness in the general case of this kind of keyword.
The constant complaining about Rust posts may suggest that opposite is true. Why don't you follow other topic if you are not interested in Rust. You are free.
I am interested in Rust. I am not interested in takes like this one, or a lot of the other "I love rust" content that lacks technical substance.
Why don't you put your interest and desires together and make something like that? I'm sure the people who are at least trying to do something would welcome the example.
Hello sir, I'm here to resolve your doubts
https://goodmanwen.github.io/Programming-Language-Benchmarks...
compared to what rust has to offer, compared to C and CPP, this is truly awesome.
https://goodmanwen.github.io/Programming-Language-Benchmarks...
compared to what rust has to offer, compared to C and CPP, this is truly awesome.
[deleted]
The funny thing is that posts like these are fine and upvoted heavily. But if someone make a post like: Tiobe states that "C++ is language of the year 2022", then its either flagged or utterly downvoted to death.
The Rust fanatics have VERY thin skin if the language they hate gets any upward-adoption news.
The Rust fanatics have VERY thin skin if the language they hate gets any upward-adoption news.
I wouldn’t care if Rust were 10x slower. Just within my career, computers have become 1000x faster. We can definitely afford a stack that might actually work.
[deleted]
My code got faster, and removed memory safety issues, but I got no upvotes :P
[deleted]
Usually everyone knows what made it better to be in Rust, especially when it comes to C and C++.
I've never seen a need to use rust, and regularly work on small projects in C. As far as I can tell, there isn't really a compelling reason to switch.
I wrote a small service to synch the datetime based on a gps/imu module with an ethernet interface. It needed to be rock solid because it was going to fly in the field (scientific instrument, not avionics). It was faster and easier to write in Rust, despite having no one else with Rust know-how in the company, the rest of the system components in C++/Python, and several months of of c and c++ experience myself. I barely knew rust and yet felt way more confident the program didn't have weird unexpected edge cases, leaks, etc. Not to mention way more ergonomic.
Security / memory safety and preventing concurrency bugs
Security is an especially big one for lots of systems
Security is an especially big one for lots of systems
My impression as a non-expert who has only dabbled in Rust is that while it is ‘easy’ by design to write memory-safe code, it is relatively difficult to write panic-free code, and by and large the ecosystem doesn't try. (I know about `no_panic`.) In some domains (e.g. the rust-analyzer panic discussed here yesterday¹) this is fine; in others “this is fine”.²
The first Ariane 5 launch is an example of the latter. The code was written in a ‘safe’ language, Ada. A conversion overflow (that, as it happened, was in fact genuinely harmless) triggered a panic that (by design) brought down the subsystem, and with it the rocket.³
¹ https://news.ycombinator.com/item?id=34775549
² http://gunshowcomic.com/648
³ http://sunnyday.mit.edu/nasa-class/Ariane5-report.html
The first Ariane 5 launch is an example of the latter. The code was written in a ‘safe’ language, Ada. A conversion overflow (that, as it happened, was in fact genuinely harmless) triggered a panic that (by design) brought down the subsystem, and with it the rocket.³
¹ https://news.ycombinator.com/item?id=34775549
² http://gunshowcomic.com/648
³ http://sunnyday.mit.edu/nasa-class/Ariane5-report.html
Interesting point.
I allow for panics when the panic is expected to never execute, i.e. logic errors.
I see how it can be problematic, and thought of adding a general logic error for such cases. However, it adds work for devs and the machine.
Still, panics can happen for allocations, where I don't know a solution.
Would you consider this as a problem as well?
If not, no_panic should suffice, right? Yeah, it might make things harder, but for rockets you probably won't use that many external crates and a bit more work should be acceptable, shouldn't it?
What would you like to see the devs and the lang team to do?
I allow for panics when the panic is expected to never execute, i.e. logic errors.
I see how it can be problematic, and thought of adding a general logic error for such cases. However, it adds work for devs and the machine.
Still, panics can happen for allocations, where I don't know a solution.
Would you consider this as a problem as well?
If not, no_panic should suffice, right? Yeah, it might make things harder, but for rockets you probably won't use that many external crates and a bit more work should be acceptable, shouldn't it?
What would you like to see the devs and the lang team to do?
I'm not knowledgeable enough about Rust's actual current state and plans to make concrete suggestions. Given the wide interest in Rust for security, I do think it's likely that in the long run significant effort will go into avoiding DOS-by-panic.
I think it's unfortunate that LLVM had no popular small targets during Rust's early years, so it didn't get much attention from embedded devlopers. Heap allocation is one place where this shows. It's not really worse than C++, though, where in principle many parts of the standard library can use a custom allocator, but handling errors is awkward, and in practice the ecosystem doesn't try. C and C++ standards also don't generally specify which library components are allowed to perform heap allocations internally.
C and C++ have ended up with small parallel ecosystems for such use cases. Since Rust aims to have one true ecosystem under cargo, it might be nice if library components could be explicitly tagged as panic-free, heap-free, etc.
I think it's unfortunate that LLVM had no popular small targets during Rust's early years, so it didn't get much attention from embedded devlopers. Heap allocation is one place where this shows. It's not really worse than C++, though, where in principle many parts of the standard library can use a custom allocator, but handling errors is awkward, and in practice the ecosystem doesn't try. C and C++ standards also don't generally specify which library components are allowed to perform heap allocations internally.
C and C++ have ended up with small parallel ecosystems for such use cases. Since Rust aims to have one true ecosystem under cargo, it might be nice if library components could be explicitly tagged as panic-free, heap-free, etc.
Rust doesn't exactly have things tagged as heap-free, but no_std category[1] contains many crates who have at least indicated that they don't use the standard library. Some may pull in liballoc and still want to do allocation, but it's better than nothing. Additionally, many packages that normally require the standard library let you opt out of that, with reduced functionality.
My team works in no-heap Rust. We use external packages. It's much easier than in any other ecosystem to do so. Even that bit above goes a very long way and saves a lot of work.
1: https://crates.io/categories/no-std
My team works in no-heap Rust. We use external packages. It's much easier than in any other ecosystem to do so. Even that bit above goes a very long way and saves a lot of work.
1: https://crates.io/categories/no-std
Comments like this make me think that you have never worked in a domain where safety is paramount (like avionics or medical technology).
People who are developing in these domains are typically using a strict subset of c or c++ and running their programs through a process of formal verification.
As far as I am aware, rust has no specification to formally verify, and the formal verification tools are all out of date (because of the rapid pace of language changes) or lacking (for example Miri lacks the ability to consider all input values because it executes your code the same way as it would normally run)
People who are developing in these domains are typically using a strict subset of c or c++ and running their programs through a process of formal verification.
As far as I am aware, rust has no specification to formally verify, and the formal verification tools are all out of date (because of the rapid pace of language changes) or lacking (for example Miri lacks the ability to consider all input values because it executes your code the same way as it would normally run)
This key!
The wealth of formal verification tools in the safety critical c and c++ world is very high. Those tools, not the compilers are what get validated during tool qualification. Ultimately it is about the formal verification, static analysis and dynamic analysis tools, as well as, traceable code execution, robustness tests etc.
A formally verified rust compiler could really be a game changer, but until then, the tools do exist to write safe c and c++, but they are expensive and adherence is low outside of the places they must be used
The wealth of formal verification tools in the safety critical c and c++ world is very high. Those tools, not the compilers are what get validated during tool qualification. Ultimately it is about the formal verification, static analysis and dynamic analysis tools, as well as, traceable code execution, robustness tests etc.
A formally verified rust compiler could really be a game changer, but until then, the tools do exist to write safe c and c++, but they are expensive and adherence is low outside of the places they must be used
Ferrous Systems is “on the last legs” of qualifying the compiler for a few different safety standards. It is true that Rust is behind in these domains, but it’s only a matter of time.
Most people aren't. I understand the hype on one level. It's fun to do great work and build high quality things. OTOH, What most of the world needs is "good enough" work rather than great work.
I haven’t, and interesting to know that C++ is used there!
I’m referring to systems software (operating systems, browsers, runtimes, backends) where formal verification is not normally used.
I’m referring to systems software (operating systems, browsers, runtimes, backends) where formal verification is not normally used.
You can just toss out names of qualities and it might impress someone with no experience but to the rest of us we're just waving our hands like "ok.. and then?" waiting for the substance, which this comment provides none of
I'm not sure I agree. If anything someone with experience has first-hand knowledge of the perils of buffer overflows, double frees, and other memory bugs. Sure we can go into more detail but it's a little disingenuous to act as if someone with experience writing C would not be able to fill in the blanks.
>someone with experience writing C would not be able to fill in the blanks.
"yeah well if you're smart you wouldn't need explanation"
except the people you're swaying with such remarks aren't the ones who already know, its the ones who are afraid to ask lest they be judged so they just kinda laugh along and parrot the smartest-bully.
"yeah well if you're smart you wouldn't need explanation"
except the people you're swaying with such remarks aren't the ones who already know, its the ones who are afraid to ask lest they be judged so they just kinda laugh along and parrot the smartest-bully.
I have never worked with Rust but seeing major operating systems and critical softwares gradually adopting, and other developers reporting less segfaults when replacing their codebase with Rust is convincing enough for me to try it out.
[deleted]
N=1, but I don't always know what made it better in Rust.
Rust and Golang projects are generally more interesting as they generally are small static binaries and have the lowest friction to try out/deploy.
It's almost the opposite effect of all the comments that appear on Electron projects regarding bloat.
It's almost the opposite effect of all the comments that appear on Electron projects regarding bloat.
There was an accumulation of trust in the fact that most rust rewrites would yield interesting results. So the gates are wide open now.
> shocking, i know!
How is most generic comment under HN Rust topic shocking?
How is most generic comment under HN Rust topic shocking?
It's just over-correction for past criticisms of other loved languages.
"Oh yeah? If X is so good, why aren't there any real software projects written in it?" etc.
"Oh yeah? If X is so good, why aren't there any real software projects written in it?" etc.
Note that Rust changed significantly from the side project days to 1.0 and above. It used to have features like Go-like green threads, for instance.
I still think this is one area Rust missed the mark. Go concurrency is quite amazing. Its fast and easy to reason about. Every language can learn something by how goroutines work here. Most importantly, it feels like you're just interacting with synchronous code. There is no "what color is your function?"[0] problem.
The fundamental primitives Rust decided to adopt are just not ergonomic by comparison, and suffers from the aforementioned "What Color Is Your Function?" problem.
An otherwise great language decided to adopt an old hand grenade in regards to async primitives
[0]: https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...
The fundamental primitives Rust decided to adopt are just not ergonomic by comparison, and suffers from the aforementioned "What Color Is Your Function?" problem.
An otherwise great language decided to adopt an old hand grenade in regards to async primitives
[0]: https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...
This is an absolutely reasonable take. The thing is, this is just a divergence in values. Rust isn’t willing to accept the overheads of that style of concurrency, and is willing to trade off on the “harder to learn but with less overhead” side of this spectrum.
There's an interesting dynamic around asynchronous code in that the way to do it the fastest is to have stackless coroutines which operate on state objects on a batched fashion. This limits what you can do, but completely eliminates a lot of the overheads that are associated with async.
The inclusion of generic async semantics at the language layer is itself a compromise. Rust may have gone a little too far down the "reduce overheads" rabbit hole given that this is the case. Go definitely didn't go far enough for high-performance use cases.
The inclusion of generic async semantics at the language layer is itself a compromise. Rust may have gone a little too far down the "reduce overheads" rabbit hole given that this is the case. Go definitely didn't go far enough for high-performance use cases.
All nice and dandy, but a coroutine, and doubly so a goroutine, is still a coloured function.
They are looking to fix that problem with keyword generics.
is there anywhere we can see whats being proposed there? I couldn't find anything, but I also may not know exactly where to look
Remember the ~ operator?
https://github.com/rust-lang/rfcs/pull/59
https://github.com/rust-lang/rfcs/pull/59
And now ~ seems to be used for keyword generics.
i may not have read the article correctly, but i see no actual evidence there that it is the "world's fastest growing language", whatever that might mean, except that there a lot of questions about it on SO (and of course posts like this on HN).
also, possibly related, isn't it strange you see almost no more haskell posts here these days?
also, possibly related, isn't it strange you see almost no more haskell posts here these days?
Based on public repos, Haskell is not growing, and Rust has overtaken it:
https://www.openhub.net/languages/compare?language_name[]=ru...
http://www.modulecounts.com/
https://www.openhub.net/languages/compare?language_name[]=ru...
http://www.modulecounts.com/
It seems the title changed. It's now "How Rust went from a side project to the world’s most-loved programming language."
The URL slug shows the old title perhaps.
The URL slug shows the old title perhaps.
i can't believe there is ANY evidence for "most-loved"! most programmers have almost certainly never used it, much less loved it.
It wins 'most loved' in the stackoverflow survey every year, so that is certainly some evidence.
the evidence is the same of the elections: if only 30% of the people vote, the most loved vote was non voting.
I don't see PHP programmers going to Stackoverflow to vote for PHP, but it still gets a lot more things done than Rust, for sure.
And not because they don't like the language, but because "normies" don't go out talking about their love for the hammer or their drill or their kitchen too... no wait, chefs talk about their knives constantly!
I don't see PHP programmers going to Stackoverflow to vote for PHP, but it still gets a lot more things done than Rust, for sure.
And not because they don't like the language, but because "normies" don't go out talking about their love for the hammer or their drill or their kitchen too... no wait, chefs talk about their knives constantly!
Ever used Stackoverflow? They do yearly surveys. I am surprised there are people not aware of them
ever heard of self-selection?
Sure, but that doesn't mean there isn't any evidence, as you claimed. A consistent result, year-over-year, in a large and long-running survey is definitely evidence. Not proof, but still evidence.
hn goes through phases; ocaml, haskell, go, react, ive been here almost 2 decades now and it's always been this way, but you used to be able to disagree and talk about it without being shunned by devotees. right now you're not even saying much negative but you're almost so grey you're effectively silenced.
[deleted]
It's great the memory-safe languages that don't sacrifice performance are growing in popularity. But I must ask, what does Rust do better than Nim?
Nim, while providing the same memory safety as Rust, doesn't do so without overhead. So Nim very expressly sacrifices performance for safety.
In rust, for example, it's possible to safely share data between threads without incurring costs of a garbage collector. Nim uses a different GC for each thread, so it naturally increases costs on a per-thread basis.
In rust, for example, it's possible to safely share data between threads without incurring costs of a garbage collector. Nim uses a different GC for each thread, so it naturally increases costs on a per-thread basis.
No more GC in Nim now there is an optional cycle collector https://nim-lang.org/blog/2020/12/08/introducing-orc.html it also offers experimental view types.
I was sort of vaguely aware of this but thank you for pointing it out! I think the point still stands, and that reference counting like this is just a different kind of garbage collection.
It certainly adds (some, not many thanks to static analysis) runtime checks, but it's also fairly distinguished from typical tracing garbage collection by being deterministic. I believe ARC/ORC also works with a shared heap via "isolated" data.
That's correct; there are two chapters of the GC Handbook on reference counting, and ye olde unified theory of garbage collection <https://dl.acm.org/doi/10.1145/1028976.1028982>.
It's not exactly like that there is cursor inference and copy elision. But ok...
It's been a few years since I've used Nim, but outside of the language itself, the tooling around Rust is absolutely incredible. Rust Analyzer, Clippy, Cargo, etc.
Network effects are big at this point. Nim doesn't have a userbase or ecosystem like Rust.
> what does Rust do better than Nim?
I can install Rust, for one thing (I’m on an M1 mac; trying the three main nim installers, one gives me an out of date version, one gives me the x86 version, and one segfaults)
Also Rust’s error messages and standard library documentation are way more helpful
Also Rust runs nearly twice as fast
(I do like the nim language, but no more or less than I like the rust language; tooling makes a big difference though)
I can install Rust, for one thing (I’m on an M1 mac; trying the three main nim installers, one gives me an out of date version, one gives me the x86 version, and one segfaults)
Also Rust’s error messages and standard library documentation are way more helpful
Also Rust runs nearly twice as fast
(I do like the nim language, but no more or less than I like the rust language; tooling makes a big difference though)
For me (and inv2004) Nim, runs faster than Rust on your RosettaBoy project.. But perf usually depends on an awful lot of territory that is routinely unexplored before conclusions are bandied about.
The Nim installation & tooling experience unfortunately can be rough. OTOH, it has like <1% the funding/exposure. Also, I find the "100s of packages dependencies" for any non-trivial Rust program to be pretty awful, as well as reading other people's Rust code (a point made more salient by all the deps).
Anyway, there are many dimensions/axes by which to evaluate most things in life and usually no objective way to weight/combine them into a single overall score. So, it's often good to keep an open mind. (Not saying you don't do so personally!)
The Nim installation & tooling experience unfortunately can be rough. OTOH, it has like <1% the funding/exposure. Also, I find the "100s of packages dependencies" for any non-trivial Rust program to be pretty awful, as well as reading other people's Rust code (a point made more salient by all the deps).
Anyway, there are many dimensions/axes by which to evaluate most things in life and usually no objective way to weight/combine them into a single overall score. So, it's often good to keep an open mind. (Not saying you don't do so personally!)
> For me (and inv2004) Nim, runs faster than Rust on your RosettaBoy project
I didn’t spot that it had improved that much; I guess I need to hurry up and brute-force my way past the installer issues to try it out :D
I didn’t spot that it had improved that much; I guess I need to hurry up and brute-force my way past the installer issues to try it out :D
If it helps, I almost always just git clone & compile Nim from source myself.. takes just a couple minutes. Never tried it on an M1, though.
I think Rust is probably great for certain types of projects that need effecient programs but the main problem I have always had is not having enough time and Rust does the reverse for me in that regard.
It is hard to learn and takes quite some time to write compared to many other popular languages. For what benefit? Most languages are fast enough and the bugs I encounter is not bugs that Rust solves. I do web dev stuff, like I would assume most of us do, and the performance bottlenecks are pretty much never due to the language being too slow.
Granted, I understand completely why large companies that work on complex systems have a use case for Rust, the main issue I have with the community is that it tries to sell itself as a solution to everything when in reality the most likely scenario for most of us is that we would be more productive and successful in basically any other language.
It is hard to learn and takes quite some time to write compared to many other popular languages. For what benefit? Most languages are fast enough and the bugs I encounter is not bugs that Rust solves. I do web dev stuff, like I would assume most of us do, and the performance bottlenecks are pretty much never due to the language being too slow.
Granted, I understand completely why large companies that work on complex systems have a use case for Rust, the main issue I have with the community is that it tries to sell itself as a solution to everything when in reality the most likely scenario for most of us is that we would be more productive and successful in basically any other language.
Rust has a nice implementation of discriminated unions/algebraic data types, which makes it easy to write the business logic with composability over inheritance. Which lang does that well with also pattern matching, non-nullability, explicit mutability etc.? Maybe OCalm? F#? Elm?
F#, Scala, Purescript, Haskell and many others are much much better in this regards than Rust. They are not replacing Rust of course because they don't focus on performance/lowlevel, but in the context of OPs question, while Rust is great, it still has a lot to catch up here.
[deleted]
Maybe I'm stupid but I don't really understand your first sentence. What does it mean? Care to elaborate?
Of course! What I meant was that in some cases composition is a more flexible approach to representing a complex (business) model than inheritance, from object oriented programming.
Rust has a nice (IMO, ergonomic) way of representing composition through a language feature called "algebraic data types", although it's sometimes called "discriminated unions" or "sum types".
Sum types combined with "pattern matching" is a particularly powerful combination that can make code very easy to write and read, IMO. But not always, so don't take it as an absolute truth. This is one of many articles that explain sum types in Haskell: https://medium.com/@willkurt/why-sum-types-matter-in-haskell...
Statically-typed languages that borrow from functional concepts like Rust, Haskell, F#, Elm and others usually support that. C# has been debating adding support for it (https://github.com/dotnet/csharplang/issues/113), but its community hasn't reached consensus yet. Dynamically-typed languages like Elixir don't benefit the same way from this without sacrificing the flexibility of the language, but in this case they're considering alternative approaches like set-theoretic types: https://elixir-lang.org/blog/2022/10/05/my-future-with-elixi....
Rust has a nice (IMO, ergonomic) way of representing composition through a language feature called "algebraic data types", although it's sometimes called "discriminated unions" or "sum types".
Sum types combined with "pattern matching" is a particularly powerful combination that can make code very easy to write and read, IMO. But not always, so don't take it as an absolute truth. This is one of many articles that explain sum types in Haskell: https://medium.com/@willkurt/why-sum-types-matter-in-haskell...
Statically-typed languages that borrow from functional concepts like Rust, Haskell, F#, Elm and others usually support that. C# has been debating adding support for it (https://github.com/dotnet/csharplang/issues/113), but its community hasn't reached consensus yet. Dynamically-typed languages like Elixir don't benefit the same way from this without sacrificing the flexibility of the language, but in this case they're considering alternative approaches like set-theoretic types: https://elixir-lang.org/blog/2022/10/05/my-future-with-elixi....
There's no concise answer, but there's a fantastic book covering and motivating his first sentence.
https://a.co/d/bZFsIyg
Domain Modelling Made Functional
https://a.co/d/bZFsIyg
Domain Modelling Made Functional
Same guy posts a lot of information about the topics on his website[1] as well. For anyone who isn't anti dotNet for various reasons such as being from Microsoft I recommend giving F# a try, it is a very nice language.
[1] - https://fsharpforfunandprofit.com/
[1] - https://fsharpforfunandprofit.com/
Same guy? Not I: i have no website.
Totally agree: i think folks dont realize F# is modernized OCaml and this is approximately a typed Lisp semantically. Very useful.
Totally agree: i think folks dont realize F# is modernized OCaml and this is approximately a typed Lisp semantically. Very useful.
I am not sure how F# which started as a .NET version of early OCaml 3 can be seen as a modernized OCaml 5? Even more so when F# has to give up on some OCaml core feature in the transition (before growing in its own language of course).
Yeah OCaml 5 seems like a different beast with the new concurrency system plus the new effects system etc. If they get a good windows install experience I want to try it out at some point but seems it is recommended currently to go through WSL or msys/cygwin (I forget which) and at this moment I'm not motivated enough to go through the hoops.
forked then modernized probably fits better, i agree
You have a shape which can be either a circle which then has a radius, or a rectangle which has width/height. The shape cannot be anything else, this is important and something you want to rely on and express in code. In C++ you can't easily do this on the language level. In Rust (albeit in a somewhat limited way) and functional languages, you can, via enums where variants can host other types.
You’re not stupid: the OP wrote a bunch of jargon that more or less nobody in the industry uses on any regular basis. It’s a similar pattern to functional programming evangelists’ rhetoric.
The short answer is this: the compiler enforces type-checked unions (called `enum` in Rust) guaranteed to hold one specific type, and requires any `match` block (cf `switch`) checking a value to exhaustively check all possible ones. That’s not the whole story, but it covers about 99.99% of the use cases the OP refers to.
The short answer is this: the compiler enforces type-checked unions (called `enum` in Rust) guaranteed to hold one specific type, and requires any `match` block (cf `switch`) checking a value to exhaustively check all possible ones. That’s not the whole story, but it covers about 99.99% of the use cases the OP refers to.
those language features are nice but they are not solving important problems and they do not justify the cost of learning and using rust for most people
> which makes it easy to write the business logic with composability over inheritance
One feature Rust is really missing is trait "inheritance" – you can't say "dispatch this trait implementation to this field" or anything like it. (The closest you can get is Deref, but that has its own quirks.)
One feature Rust is really missing is trait "inheritance" – you can't say "dispatch this trait implementation to this field" or anything like it. (The closest you can get is Deref, but that has its own quirks.)
Seems like a bit of survivor bias at play too in that narrative. Don’t pretty much all languages start off that way?
I'd guess, "pretty much all languages" don't have any growth at all.
Going from almost zero to some small number may present a rate of increase that appears huge.
Going from very large to even larger still may be a much lower rate of increase.
Never let the facts get the way of a good headline?
Going from very large to even larger still may be a much lower rate of increase.
Never let the facts get the way of a good headline?
Well, if you use relative rates of growth, following an exponential curve, yes, that happens.
If you use absolute rates of growth, following a linear curve, no, that's bullshit.
The article has no numbers, but appears very strongly to use the second definition.
If you use absolute rates of growth, following a linear curve, no, that's bullshit.
The article has no numbers, but appears very strongly to use the second definition.
> If you use absolute rates of growth
I'm not sure what an "absolute rate" (of growth) is, can you explain?
Aren't growth rates usually (always?) expressed as a percentage change of a variable over time? How could that be anything other than relative?
I'm not sure what an "absolute rate" (of growth) is, can you explain?
Aren't growth rates usually (always?) expressed as a percentage change of a variable over time? How could that be anything other than relative?
growth, definition: the act or process, or a manner of growing; development; gradual increase.
If something grows from 1 to 2 it doubled.
If something grows from 100 to 101 its growth was 1%.
In absolute terms it's the same amount.
So you got it backwards.
If something grows from 1 to 2 it doubled.
If something grows from 100 to 101 its growth was 1%.
In absolute terms it's the same amount.
So you got it backwards.
True.
But I'd assume that most are just used by their creators.
But I'd assume that most are just used by their creators.
These days I code primarily in C++, which is what Rust seemingly is designed to replace. It doesn't, as far as I can tell. I optimize directly for the hardware I'm running on, which typically gives me 10-100x performance improvements. Controlling how memory is managed is critical.
It's great when something new and better comes along if that's really the case, but I've seen the "incrementally better in certain use cases" play many times before.
It's great when something new and better comes along if that's really the case, but I've seen the "incrementally better in certain use cases" play many times before.
This can be done with Rust as well, using unsafe code block if absolutely necessary. And only those blocks have to be reviewed for footguns, as opposed to your entire C++ code.
Also even a 10x speedup sounds much. In Rust, instead using .get_unchecked() (the C++ equivalent) instead of using .get() is typically only a neglegible improvement of a few percentage points in that particular loop or whatever.
Also even a 10x speedup sounds much. In Rust, instead using .get_unchecked() (the C++ equivalent) instead of using .get() is typically only a neglegible improvement of a few percentage points in that particular loop or whatever.
> I optimize directly for the hardware I'm running on, which typically gives me 10-100x performance improvements. Controlling how memory is managed is critical.
What makes you think you can't control how memory is managed in Rust? Rust doesn't have "automatic" memory management, it has a compiler that can help ensure you are managing memory correctly, and force you to type "unsafe" when you are doing things it doesn't understand.
What makes you think you can't control how memory is managed in Rust? Rust doesn't have "automatic" memory management, it has a compiler that can help ensure you are managing memory correctly, and force you to type "unsafe" when you are doing things it doesn't understand.
> it has a compiler that can help ensure you are managing memory correctly, and force you to type "unsafe" when you are doing things it doesn't understand.
Well it's a bit more subtle than that if we're honest.
Arguably, Rust does make a number of memory layouts (self referential structs, per struct allocators, non thread local addresses, etc) much harder to accomplish than "typing unsafe".
Well it's a bit more subtle than that if we're honest.
Arguably, Rust does make a number of memory layouts (self referential structs, per struct allocators, non thread local addresses, etc) much harder to accomplish than "typing unsafe".
If you self-reference using pointers and guarantee the struct will never move, you don't even need unsafe. If you self-reference using offsets from the struct's base pointer, you need a splash of unsafe but your struct can be freely moved without invalidating its self-referential "pointers".
Per-struct allocators are a work in progress (see https://github.com/rust-lang/wg-allocators/issues/48).
Not sure what "non thread local addresses" means, but in my experience Rust is pretty good at sending data between threads (without moving it).
Per-struct allocators are a work in progress (see https://github.com/rust-lang/wg-allocators/issues/48).
Not sure what "non thread local addresses" means, but in my experience Rust is pretty good at sending data between threads (without moving it).
> If you self-reference using pointers and guarantee the struct will never move, you don't even need unsafe
I have a hard time seeing how you could use self references without a combination of raw pointers, pins/projects, and unsafe code. The tediousness of doing so is pretty much a no-go for any sane developer.
The only sane solution seems to be a generous sprinkle of Arcs, which is _not_ okay in high performance scenarios.
> Per-struct allocators are a work in progress
Yes, and most of us don't really want to use nightly in production. It's been years of work on the allocator work group already, and there's probably still years to wait before a stable release.
> Not sure what "non thread local addresses" means, but in my experience Rust is pretty good at sending data between threads
Well I mean overall any way to allow a somewhat eased setup for storing and retrieving objects to/from shared memory, across processes that do not map said memory at the same location. This is very very annoying to implement in Rust at the moment.
Don't get me wrong though, I think Rust has a lot to offer. But when you dive in even slightly technical subjects in Rust, it soon becomes obvious that the power of C/C++ is far from "just type unsafe" away.
I have a hard time seeing how you could use self references without a combination of raw pointers, pins/projects, and unsafe code. The tediousness of doing so is pretty much a no-go for any sane developer.
The only sane solution seems to be a generous sprinkle of Arcs, which is _not_ okay in high performance scenarios.
> Per-struct allocators are a work in progress
Yes, and most of us don't really want to use nightly in production. It's been years of work on the allocator work group already, and there's probably still years to wait before a stable release.
> Not sure what "non thread local addresses" means, but in my experience Rust is pretty good at sending data between threads
Well I mean overall any way to allow a somewhat eased setup for storing and retrieving objects to/from shared memory, across processes that do not map said memory at the same location. This is very very annoying to implement in Rust at the moment.
Don't get me wrong though, I think Rust has a lot to offer. But when you dive in even slightly technical subjects in Rust, it soon becomes obvious that the power of C/C++ is far from "just type unsafe" away.
> I have a hard time seeing how you could use self references without a combination of raw pointers, pins/projects, and unsafe code. The tediousness of doing so is pretty much a no-go for any sane developer.
You just do it. I can't recall a good example at the moment, so I've just thrown together a load of Cells: the thing I was doing when I learnt this technique didn't have any Cells in it.
https://play.rust-lang.org/?version=nightly&edition=2021&gis...
Strictly speaking, this is only needed if you want to use Rust's standard library types with custom allocators. You've been able to have per-struct allocators for your own types since long before I learnt the language.
> Well I mean overall any way to allow a somewhat eased setup for storing and retrieving objects to/from shared memory, across processes that do not map said memory at the same location.
Can't you just store offsets into the memory region, and PhantomData references, then unsafely index the mmap'd region when you need an actual reference? Seems like the same thing you'd do in C, except the function you abstract that with can be a method instead. (Unless I'm still misunderstanding.)
You just do it. I can't recall a good example at the moment, so I've just thrown together a load of Cells: the thing I was doing when I learnt this technique didn't have any Cells in it.
https://play.rust-lang.org/?version=nightly&edition=2021&gis...
#[derive(Debug)]
struct SlotMachine<'a> {
slots: Vec<Cell<i32>>,
current: Cell<Option<&'a Cell<i32>>>,
}
fn main() {
let machine = SlotMachine {
slots: vec![Cell::new(0); 5],
current: Cell::new(None),
};
machine.current.set(Some(&machine.slots[4]));
machine.slots[4].set(12);
println!("{:#?}", machine);
}
> Yes, and most of us don't really want to use nightly in production.Strictly speaking, this is only needed if you want to use Rust's standard library types with custom allocators. You've been able to have per-struct allocators for your own types since long before I learnt the language.
> Well I mean overall any way to allow a somewhat eased setup for storing and retrieving objects to/from shared memory, across processes that do not map said memory at the same location.
Can't you just store offsets into the memory region, and PhantomData references, then unsafely index the mmap'd region when you need an actual reference? Seems like the same thing you'd do in C, except the function you abstract that with can be a method instead. (Unless I'm still misunderstanding.)
> What makes you think you can't control how memory is managed in Rust?
experienced C++ programmers says "Rust is great but very young and still C++ is better for my use case".
Rust supporter replies "what makes you think you know better than us what it is better for you?"
Welcoming community, they said.
experienced C++ programmers says "Rust is great but very young and still C++ is better for my use case".
Rust supporter replies "what makes you think you know better than us what it is better for you?"
Welcoming community, they said.
Neither of those paraphrasings seem to line up with their source material
Are you sure?
Read again
> I optimize directly for the hardware I'm running on, which typically gives me 10-100x performance improvements. Controlling how memory is managed is critical.
> What makes you think you can't control how memory is managed in Rust?
> Arguably, Rust does make a number of memory layouts (self referential structs, per struct allocators, non thread local addresses, etc) much harder to accomplish than "typing unsafe".
So basically, the right question would be "can you explain what you mean that Rust can't control how memory is managed"?
Because the author knew, the Rust supporter didn't and confused "work in progress" with "I need it now because I'm using it now in production in my daily job"
Read again
> I optimize directly for the hardware I'm running on, which typically gives me 10-100x performance improvements. Controlling how memory is managed is critical.
> What makes you think you can't control how memory is managed in Rust?
> Arguably, Rust does make a number of memory layouts (self referential structs, per struct allocators, non thread local addresses, etc) much harder to accomplish than "typing unsafe".
So basically, the right question would be "can you explain what you mean that Rust can't control how memory is managed"?
Because the author knew, the Rust supporter didn't and confused "work in progress" with "I need it now because I'm using it now in production in my daily job"
Yup, I’ve read it again, and I’m still pretty sure that you’re responding mostly to your own assumptions and not really responding to what was written :)
We've established that you lack the ability to understand a text, then.
I very much enjoy Rust and write a fair bit of C++ as well. I don’t think Rust will replace C++ completely but it will definitely significantly eat into its market share for certain types of applications. In the past if you absolutely needed a “modern” language and needed performance you’d basically only go C++ (or maybe C).
IMO if you’re writing a highly concurrent or parallel application it’s hard to deny how much more productive and safer it is to write it in Rust. Optimizing cpu instructions in a single thread? Rust might just be an alternative and not competitive.
IMO if you’re writing a highly concurrent or parallel application it’s hard to deny how much more productive and safer it is to write it in Rust. Optimizing cpu instructions in a single thread? Rust might just be an alternative and not competitive.
> C++, which is what Rust seemingly is designed to replace. It doesn't, as far as I can tell.
You can't replace C++:
1. Well-functioning, mission-critical systems that were made in C++ aren't being replaced.
2. Anything GPU and ML-related is still better solved in Python/C++.
3. Anything that depends on scalable, high-performance data structures, C++ still has a better selection.
What "replace C++" can mean is: There are use-cases where Rust and C++ overlap where the Rust story is maturing, and you can pick Rust in those cases instead of C++ if you're not already invested in C++. But either if you have existing C++ code that works well, or you have deep C++ knowledge, or you are in one of the categories where Rust is not on par yet, there's still no competition.
You can't replace C++:
1. Well-functioning, mission-critical systems that were made in C++ aren't being replaced.
2. Anything GPU and ML-related is still better solved in Python/C++.
3. Anything that depends on scalable, high-performance data structures, C++ still has a better selection.
What "replace C++" can mean is: There are use-cases where Rust and C++ overlap where the Rust story is maturing, and you can pick Rust in those cases instead of C++ if you're not already invested in C++. But either if you have existing C++ code that works well, or you have deep C++ knowledge, or you are in one of the categories where Rust is not on par yet, there's still no competition.
> 1. Well-functioning, mission-critical systems that were made in C++ aren't being replaced.
Very true. There is a lot of existing working code that is not going away and will even still need to be maintained for decades.
> 2. Anything GPU and ML-related is still better solved in Python/C++.
Can be done in Python/Rust
> 3. Anything that depends on scalable, high-performance data structures, C++ still has a better selection.
Why is that? Rust has equally high performance data structures. Even more perfortant in some cases (restrict by default, destructive move, easier concurrency)
Very true. There is a lot of existing working code that is not going away and will even still need to be maintained for decades.
> 2. Anything GPU and ML-related is still better solved in Python/C++.
Can be done in Python/Rust
> 3. Anything that depends on scalable, high-performance data structures, C++ still has a better selection.
Why is that? Rust has equally high performance data structures. Even more perfortant in some cases (restrict by default, destructive move, easier concurrency)
> [Anything GPU and ML-related] Can be done in Python/Rust
Can be done in Brainfuck. You just need to write the Cuda bindings.
> > C++ still has a better selection.
> Why is that?
Because C++ was around for longer.
For people who are more invested in Rust (myself included), extending Rust's selection is seen as a great endeavour.
I personally keep a list of things I wish to "oxidize". :-)
Can be done in Brainfuck. You just need to write the Cuda bindings.
> > C++ still has a better selection.
> Why is that?
Because C++ was around for longer.
For people who are more invested in Rust (myself included), extending Rust's selection is seen as a great endeavour.
I personally keep a list of things I wish to "oxidize". :-)
There are definitely fringe edge cases where C++ can do things that Rust simply cannot, currently.
I'm thinking of things like Herb Sutter's deferred_heap (https://github.com/hsutter/gcpp) that give you GC-like abstraction. It's pretty cool that this is possible to write in vanilla C++ with decent ergonomics. I tried to make something similar awhile back in Rust and hit a wall in terms of making something that would be pleasant to use.
Rust has several on-going experiments with making a nice GC, along with good support for arenas. (If you can use arenas, they're great.)
I'm thinking of things like Herb Sutter's deferred_heap (https://github.com/hsutter/gcpp) that give you GC-like abstraction. It's pretty cool that this is possible to write in vanilla C++ with decent ergonomics. I tried to make something similar awhile back in Rust and hit a wall in terms of making something that would be pleasant to use.
Rust has several on-going experiments with making a nice GC, along with good support for arenas. (If you can use arenas, they're great.)
Are you sure you're not confusing it with Swift, or perhaps running Rust in unoptimized debug mode (-O0)?
Rust goes as low-level as C (there's literally c2rust source-to-source translator). It gives you full control over all allocations and indirections. It's even more efficient than C++ in a few places, e.g. it has a more efficient ABI for unique_ptr, doesn't call destructors redundantly after a move, doesn't need isa pointer in structs with virtual methods.
Rust generates native code using LLVM, and even has a bit stricter semantics that allow better optimizations (notably immutability and mutable aliasing are stricter than in C and C++).
Rust goes as low-level as C (there's literally c2rust source-to-source translator). It gives you full control over all allocations and indirections. It's even more efficient than C++ in a few places, e.g. it has a more efficient ABI for unique_ptr, doesn't call destructors redundantly after a move, doesn't need isa pointer in structs with virtual methods.
Rust generates native code using LLVM, and even has a bit stricter semantics that allow better optimizations (notably immutability and mutable aliasing are stricter than in C and C++).
Same here. We do a lot of "trust me, it's OK" operations in the name of performance, like very complex ownership semantics, manually issuing memory barriers in multithreaded scenarios, etc. Can't do any of that in Rust. The borrow checker usually forces a different design which is conceptually simpler and has fewer assumptions baked in (you end up with quite a bit of Rc/Arc, RefCells, etc.) but sacrifices quite a lot of speed.
This has been my experience with Rust as well. The safety actually does cost some performance. Just like how C++'s "zero-cost" abstractions cost something.
It seems like a straightforward trade between speed and safety to me, but nobody in the Rust community wants to admit it. As such, there aren't a lot of public benchmarks of applications out there that can help the rest of us figure out when we actually should use rust - when the performance is worth the safety (no, Rust evangelists, that kind of safety is not always worth it, and no, we don't always pay the same costs for it).
It seems like a straightforward trade between speed and safety to me, but nobody in the Rust community wants to admit it. As such, there aren't a lot of public benchmarks of applications out there that can help the rest of us figure out when we actually should use rust - when the performance is worth the safety (no, Rust evangelists, that kind of safety is not always worth it, and no, we don't always pay the same costs for it).
I understand exactly what you mean at the conceptual level, but I've consistently found speedups over c++ in complex applications.
There is a lot of C++ code out there. A lot of it was not written by people who understand performance or who care. It is very easy to take that kind of code and make it faster, even without a switch to Rust.
The examples I have seen where a Rust rewrite is faster than original C++ code usually have glaring performance issues in the C++: Often, it is code that does a ton of unnecessary copies. The Rust code often doesn't copy as much because the Rust language makes that kind of copying inconvenient or because the person doing the rewrite is a Rust expert and not a C++ expert. The other kind of speedup I have seen is when people swap a C++ std::map for a Rust btree_map, and don't realize that absl::btree_map (a C++ btree map in Google's library) is what Rust's btree_map is based on.
I haven't seen any examples where C or C++ code written with performance in mind gets a rewrite to Rust and goes faster, and I have seen the opposite.
The examples I have seen where a Rust rewrite is faster than original C++ code usually have glaring performance issues in the C++: Often, it is code that does a ton of unnecessary copies. The Rust code often doesn't copy as much because the Rust language makes that kind of copying inconvenient or because the person doing the rewrite is a Rust expert and not a C++ expert. The other kind of speedup I have seen is when people swap a C++ std::map for a Rust btree_map, and don't realize that absl::btree_map (a C++ btree map in Google's library) is what Rust's btree_map is based on.
I haven't seen any examples where C or C++ code written with performance in mind gets a rewrite to Rust and goes faster, and I have seen the opposite.
> There is a lot of C++ code out there. A lot of it was not written by people who understand performance or who care. It is very easy to take that kind of code and make it faster, even without a switch to Rust.
Cliff Biffle's great series of blog posts called "Learn Rust the Dangerous Way" takes the fastest C program from a benchmark game entry, rewrites it naïvely in Rust using copious amounts of `unsafe`, and then transforms it into program without `unsafe` while keeping it idiomatic. The last version is faster than the C implementation.
It's a toy example but it's real-world example.
http://cliffle.com/p/dangerust/
Cliff Biffle's great series of blog posts called "Learn Rust the Dangerous Way" takes the fastest C program from a benchmark game entry, rewrites it naïvely in Rust using copious amounts of `unsafe`, and then transforms it into program without `unsafe` while keeping it idiomatic. The last version is faster than the C implementation.
It's a toy example but it's real-world example.
http://cliffle.com/p/dangerust/
I'll read it and take a look. I am aware that Rust does very well on the benchmarks game.
However, the benchmarks game (and microbenchmark-based comparisons in general) is hard to take seriously if you are thinking about application performance. Some languages microbenchmark very well, but don't translate that to system performance (C is the poster child of this effect), and some microbenchmark poorly but work very well in practical systems (Go is the most popular language with a big gap here, but some functional language like OCaml or Haskell probably has the biggest gap).
The reasons for these gaps can include things like it being harder to use the optimal data structure for your application (eg C code using red-black trees instead of btrees in 2023) and large code size causing terrible caching behavior (heavily templated C++). I also remember seeing something here about some non-optimal calling convention in the Rust compiler, which would be another thing that shows up in a system that doesn't in a microbenchmark.
Microbenchmarks are not a good replacement for system-level comparisons.
However, the benchmarks game (and microbenchmark-based comparisons in general) is hard to take seriously if you are thinking about application performance. Some languages microbenchmark very well, but don't translate that to system performance (C is the poster child of this effect), and some microbenchmark poorly but work very well in practical systems (Go is the most popular language with a big gap here, but some functional language like OCaml or Haskell probably has the biggest gap).
The reasons for these gaps can include things like it being harder to use the optimal data structure for your application (eg C code using red-black trees instead of btrees in 2023) and large code size causing terrible caching behavior (heavily templated C++). I also remember seeing something here about some non-optimal calling convention in the Rust compiler, which would be another thing that shows up in a system that doesn't in a microbenchmark.
Microbenchmarks are not a good replacement for system-level comparisons.
> … hard to take seriously…
Even when we're shown "Benchmarks are a crock" ?
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
> Microbenchmarks are not a good replacement for system-level comparisons.
For example —
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Even when we're shown "Benchmarks are a crock" ?
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
> Microbenchmarks are not a good replacement for system-level comparisons.
For example —
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
I think we're in agreement here. Personally, I was really looking forward to seeing "we rewrote our database in Rust from C++ and QPS improved 5% because fast code was easier to write." This kind of benchmark is not BS, and actually would save you real money.
Instead, the main arguments for the claim that Rust is the same speed as C++ are microbenchmarks, which actually are pretty useless when you are comparing very different implementations. The time they are useful is when you are refining an implementation.
If you want to scrutinize the benchmarks game even further, they use gcc for their c compiler, where clang would probably be a better choice since the benchmarks are arithmetic-heavy.
Instead, the main arguments for the claim that Rust is the same speed as C++ are microbenchmarks, which actually are pretty useless when you are comparing very different implementations. The time they are useful is when you are refining an implementation.
If you want to scrutinize the benchmarks game even further, they use gcc for their c compiler, where clang would probably be a better choice since the benchmarks are arithmetic-heavy.
When you get sufficiently close to the metal, the performance gains seem to be coming from better algorithms rather than from the programming language. Like you are saying:
> The reasons for these gaps can include things like it being harder to use the optimal data structure for your application (eg C code using red-black trees instead of btrees in 2023)
Bryan Cantrill described this experience[1] and maybe that is exactly what you are referring to.
But if you're just looking for a language to get work done with, does it matter if Rust is faster because of better off-the-shelf data structures and algorithms or because of some inherent magic in the programming language?
[1] See point 9 here: http://dtrace.org/blogs/bmc/2018/09/18/falling-in-love-with-...
> The reasons for these gaps can include things like it being harder to use the optimal data structure for your application (eg C code using red-black trees instead of btrees in 2023)
Bryan Cantrill described this experience[1] and maybe that is exactly what you are referring to.
But if you're just looking for a language to get work done with, does it matter if Rust is faster because of better off-the-shelf data structures and algorithms or because of some inherent magic in the programming language?
[1] See point 9 here: http://dtrace.org/blogs/bmc/2018/09/18/falling-in-love-with-...
Yes, because my current alternative (modern C++ with Folly/Absl) provides those data structures already, so there's no real benefit to using the new thing.
That's great for you! Then stick with your current setup.
I don't already know C++. For me, learning Rust is easier than learning safe C++. I imagine that there are many people in a similar situation for whom Rust makes more sense than C++. That doesn't mean that it makes more sense for everyone.
I don't already know C++. For me, learning Rust is easier than learning safe C++. I imagine that there are many people in a similar situation for whom Rust makes more sense than C++. That doesn't mean that it makes more sense for everyone.
> This kind of benchmark is not BS, and actually would save you real money.
And would cost someone else real money to do — so microbenchmarks ;-)
> … they use gcc for their c compiler, where clang would probably be a better choice…
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
And would cost someone else real money to do — so microbenchmarks ;-)
> … they use gcc for their c compiler, where clang would probably be a better choice…
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Cool, I didn't realize that gcc was actually performing better than clang in the examples I saw.
How big does a program need to be in order to stop counting as a microbenchmark?
Enough to stop performance slippage due to the increased amount of code and context. Unfortunately, the unit size is intentionally vague. For a lot of HPC applications, it's a small unit since they do the same math over and over again on large vectors (effectively the same as the microbenchmark). For databases and programs with significant business logic, it's a huge unit, almost a full-system test.
For the companies that re-wrote their databases, login systems, and other similar things in Rust, a real benchmark comparison would be pretty easy, and they probably did it internally anyway. Hook one of your servers up to an artificial load generator and see how much it can take.
For the companies that re-wrote their databases, login systems, and other similar things in Rust, a real benchmark comparison would be pretty easy, and they probably did it internally anyway. Hook one of your servers up to an artificial load generator and see how much it can take.
Few years back, Convey[1] has apparently outran HAProxy in an alleged benchmark by the author[2]. That's a one man project (now abandoned, sadly) outrunning a decade old product built by an enterprise company AND a big community AND spearheaded and designed by a data structure genius. Granted, only in one of many tricks HAProxy can pull, but still. Not a database but indeed a concurrent world-facing RealWork software. If true (didn't actually check myself), I'd say it fits your bill.
Personally, I read that as "can be as fast as, but without you having to be Willy Tarreau level genius" which is all I need.
It's easier/more-intuitive to do a lot of things in C++, but safe, high performing C++ is certainly harder than safe, high performing Rust for huge swaths of use-cases. Also, as has been mentioned, its type system that benefitted from the PL research since the 80s also allows for nicer expression of business logic. In particular, this means that in Rust, unlike C, Go, or even C++ in great part, you are not writing in the same low-level intricate language at every level of your stack i.e. it can be a nicer high-level experience the higher you go if you designed your lower tiers well.
And that last thing to me is the biggest advantage it has over the competition.
Off course, there is also the fact that juggling dependencies in a non-trivial C++ project was a nightmare until recently with vcpkg and it's manifest mode and that will take probably another decade to become commonplace in the ecosystem (if ever).
[1]: https://github.com/bparli/convey [2]: https://bparli.medium.com/adventures-in-rust-and-load-balanc...
Personally, I read that as "can be as fast as, but without you having to be Willy Tarreau level genius" which is all I need.
It's easier/more-intuitive to do a lot of things in C++, but safe, high performing C++ is certainly harder than safe, high performing Rust for huge swaths of use-cases. Also, as has been mentioned, its type system that benefitted from the PL research since the 80s also allows for nicer expression of business logic. In particular, this means that in Rust, unlike C, Go, or even C++ in great part, you are not writing in the same low-level intricate language at every level of your stack i.e. it can be a nicer high-level experience the higher you go if you designed your lower tiers well.
And that last thing to me is the biggest advantage it has over the competition.
Off course, there is also the fact that juggling dependencies in a non-trivial C++ project was a nightmare until recently with vcpkg and it's manifest mode and that will take probably another decade to become commonplace in the ecosystem (if ever).
[1]: https://github.com/bparli/convey [2]: https://bparli.medium.com/adventures-in-rust-and-load-balanc...
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
"Milli benchmarks are not really hard
Micro benchmarks are challenging, but OK
Nano benchmarks are the damned beasts!"
Slide 19
https://shipilev.net/talks/devoxx-Nov2013-benchmarking.pdf
"Milli benchmarks are not really hard
Micro benchmarks are challenging, but OK
Nano benchmarks are the damned beasts!"
Slide 19
https://shipilev.net/talks/devoxx-Nov2013-benchmarking.pdf
Also gcc #9 n-body program was converted to Rust #9 —
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
You've linked to an implementation full of hand-written SIMD, I'm not sure that's a great comparison one way or the other.
Which is my biggest gripe with benchmark games. There really ought to be strict categories for "straightforward, idiomatic code someone with 3 YoE could write", "optimized-but-still maintainable code an experienced senior engineer would write", and "unrestricted wizardry".
Which is my biggest gripe with benchmark games. There really ought to be strict categories for "straightforward, idiomatic code someone with 3 YoE could write", "optimized-but-still maintainable code an experienced senior engineer would write", and "unrestricted wizardry".
Please provide a magic trick that will assign programs to "strict categories" in a way that no one will dispute :-)
> … straightforward, idiomatic code…
Even with tiny programs, once you ask for "idiomatic code" things stop being straightforward: different languages do things differently —
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
> … hand-written SIMD…
One approach is to filter those programs into their own section — hand-written vector instructions | "unsafe".
Another is to use source code size as a proxy —
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
> … straightforward, idiomatic code…
Even with tiny programs, once you ask for "idiomatic code" things stop being straightforward: different languages do things differently —
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
> … hand-written SIMD…
One approach is to filter those programs into their own section — hand-written vector instructions | "unsafe".
Another is to use source code size as a proxy —
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
It seems inherently difficult to define strict categories around the soft constraints that you are listing.
But it would be interesting to try to approximate something like those categories. The project repo[1] contains the following call for idiomatic code:
But it would be interesting to try to approximate something like those categories. The project repo[1] contains the following call for idiomatic code:
Please, people ask to see more "idiomatic" programs —
- we already have enough exhaustively optimized Rust and C programs.
- we already have enough hand-written vector SIMD and "unsafe" programs.
Thank you.
[1] https://salsa.debian.org/benchmarksgame-team/benchmarksgame>Often, it is code that does a ton of unnecessary copies.
Often, code written in C / C++ does unnecessary copies precisely because the risk of avoiding those copies is hours of debugging, crashes in production, or security flaws.
So this is a legitimate benefit of Rust. Being able to code more aggressively up front, without fear of something blowing up in your face later, or much later when the intern touches the wrong line.
>I haven't seen any examples where C or C++ code written with performance in mind gets a rewrite to Rust and goes faster, and I have seen the opposite.
Here's one from Bryan Cantrill
http://dtrace.org/blogs/bmc/2018/09/28/the-relative-performa...
The point he makes is that while Rust is not strictly faster than C in most cases, it gives you the comfort of being able to use more highly optimized libraries and data structures without needing to have the extreme level of trust in the author that you do in C / C++. This is basically the same argument.
Often, code written in C / C++ does unnecessary copies precisely because the risk of avoiding those copies is hours of debugging, crashes in production, or security flaws.
So this is a legitimate benefit of Rust. Being able to code more aggressively up front, without fear of something blowing up in your face later, or much later when the intern touches the wrong line.
>I haven't seen any examples where C or C++ code written with performance in mind gets a rewrite to Rust and goes faster, and I have seen the opposite.
Here's one from Bryan Cantrill
http://dtrace.org/blogs/bmc/2018/09/28/the-relative-performa...
The point he makes is that while Rust is not strictly faster than C in most cases, it gives you the comfort of being able to use more highly optimized libraries and data structures without needing to have the extreme level of trust in the author that you do in C / C++. This is basically the same argument.
This is a comparison with C that I am familiar with. It illustrates the reasons why C++ won for many applications (compared to C). The author also is on record as someone who hates C++, and is very careful about not making any claims in that blog post about C++ because that's not his area of expertise.
Compared to C, where a data structure library is at best a heap of cobbled-together macros that make a lot of assumptions about the underlying types, C++ has well-developed libraries for all of the data structures mentioned.
And you need to trust the author plenty to make a btree that works - that is a very complicated data structure. It's not just about memory safety, there can be a lot of functional bugs, too. The author of the C++ one is Google/Facebook, who I trust to write a solid library, while the author of the Rust one is someone who was inspired by the C++ version.
At this point, both are well-tested, but there are a lot of Rust libs that are in the same position, but relatively untested.
Compared to C, where a data structure library is at best a heap of cobbled-together macros that make a lot of assumptions about the underlying types, C++ has well-developed libraries for all of the data structures mentioned.
And you need to trust the author plenty to make a btree that works - that is a very complicated data structure. It's not just about memory safety, there can be a lot of functional bugs, too. The author of the C++ one is Google/Facebook, who I trust to write a solid library, while the author of the Rust one is someone who was inspired by the C++ version.
At this point, both are well-tested, but there are a lot of Rust libs that are in the same position, but relatively untested.
True: not my area of expertise as I have only written ~100,000 lines of C++ -- and that that is insufficient for C++ to be an area of expertise is itself very revealing...
It's true, and it is a big problem with C++. I'm not sure if you were being sarcastic here, but if those 100,000 lines are not heavily back-weighted towards 2014 and later, that amount of code probably doesn't make you a C++ expert unless you were doing things like writing parts of boost (or another template library) or you happened to decide to read a few hundred pages of the spec recently.
The language-change whiplash that people accuse Rust of happens to C++ folks who leave the language for several years, since "idiomatic" C++ has changed substantially over the last 20 years.
EDIT - Just to clarify, there are SO MANY different ways to do things in C++ that the way to really learn C++ is by reading (both good code and the spec), not by writing. It's very easy to write a ton of code and not actually do it in the fastest/best/most idiomatic way. This is complicated by the fact that a ton of C++ examples out there are wrong. It's really an electrical engineer's language at this point - read all the datasheets if you want to avoid getting shot in the foot (and still get shot in the foot anyway).
The language-change whiplash that people accuse Rust of happens to C++ folks who leave the language for several years, since "idiomatic" C++ has changed substantially over the last 20 years.
EDIT - Just to clarify, there are SO MANY different ways to do things in C++ that the way to really learn C++ is by reading (both good code and the spec), not by writing. It's very easy to write a ton of code and not actually do it in the fastest/best/most idiomatic way. This is complicated by the fact that a ton of C++ examples out there are wrong. It's really an electrical engineer's language at this point - read all the datasheets if you want to avoid getting shot in the foot (and still get shot in the foot anyway).
> or because the person doing the rewrite is a Rust expert and not a C++ expert
On this subject... it's much easier to become a Rust expert than a C++ expert.
I do expect the world to have more Rust experts than C++ ones today, even with much lower usage of the language and much less time for people to learn it.
On this subject... it's much easier to become a Rust expert than a C++ expert.
I do expect the world to have more Rust experts than C++ ones today, even with much lower usage of the language and much less time for people to learn it.
I bet you'd see speedups if you rewrote in C++, too.
Good point, but what is the comparative effort for both of those rewrites making similar performance improvements, and what skill level in the coder is needed to realize those similar improvements?
E.g., will the C++ rewrite for X improvement take longer, or require a more highly skilled programmer, or would the Rust programmer require some high level of expertise to yield the results but a junior C++ guy/gal could knock it out quickly?
Has anyone done real comparisons of this sort, such as taking software package X and assigning a performance rewrite to a junior Rust dev, a senor Rust dev, a junior C++ dev and a senior C++ dev, giving each a couple weeks then checking the yielded performance?
Also, how does this interact on teams? It's been a long time since I've written any C++, and I've not tried Rust, but it seems some of the Rust safety features make it harder for devs to step on each other's toes.
E.g., will the C++ rewrite for X improvement take longer, or require a more highly skilled programmer, or would the Rust programmer require some high level of expertise to yield the results but a junior C++ guy/gal could knock it out quickly?
Has anyone done real comparisons of this sort, such as taking software package X and assigning a performance rewrite to a junior Rust dev, a senor Rust dev, a junior C++ dev and a senior C++ dev, giving each a couple weeks then checking the yielded performance?
Also, how does this interact on teams? It's been a long time since I've written any C++, and I've not tried Rust, but it seems some of the Rust safety features make it harder for devs to step on each other's toes.
[deleted]
This series of posts disagrees: http://cliffle.com/p/dangerust/1/
Spoiler: the end result uses idiomatic Rust, doesn't use unsafe and is faster than the hand-optimized version in C (and hand optimized one in Rust).
Spoiler: the end result uses idiomatic Rust, doesn't use unsafe and is faster than the hand-optimized version in C (and hand optimized one in Rust).
> The safety actually does cost some performance.
I thought the safety was compile time optimization and semantic analysis, to enable code generated to feature performance optimization that reflects in improved performance at runtime.
So, where are you seeing performance penalties?
I thought the safety was compile time optimization and semantic analysis, to enable code generated to feature performance optimization that reflects in improved performance at runtime.
So, where are you seeing performance penalties?
I am not enough of a Rust compiler expert to tell you exactly where the slowdowns show up, but the common theme has been that a benchmark of a small section of the critical path shows equal performance (sometimes a little faster, sometimes a little slower), and then when you expand to a larger scope, benchmarks start to slow down in comparison to their C++ alternatives.
My intuitive guesses would be that the culprit is actually either larger code size, worse code layout, being unable to optimize certain code sections to the same level (undefined behavior in C++ is actually helpful for speed, and not all of it is actually unsafe), something about how calling conventions or struct layouts differ, or another "second-order" effect.
My intuitive guesses would be that the culprit is actually either larger code size, worse code layout, being unable to optimize certain code sections to the same level (undefined behavior in C++ is actually helpful for speed, and not all of it is actually unsafe), something about how calling conventions or struct layouts differ, or another "second-order" effect.
that's interesting ... thank you
In which cases do you not manage how memory is allocated in Rust?
You're probably running Rust code in debug mode, or something else is going on. Without more info, hard to say. But for tasks where the purpose is to write the fastest code possible, Rust is very competitive and regularly outperforms C and C++. Sure there are perf differences, but 10-100x figures are unheard of unless you're doing something really wrong.
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
10 - 100x vs what?
Having written both my sense is that C++ will indeed be ultimately faster, but with a lot of work. You can get pretty close with Rust, with less pulling your hair out, and much faster coding time. Whether that's worth the difference to a fully optimized C++ depends on what you're up to.
In Github's analysis of fasting growing language they state that Hashicorp Configuration Language was the fastest from 2021 to 2022. In 2021 from Jetbrains it is in the top five of languages to adopt and or replace. I would like to see the data that MIT is using to figure out their thesis.
https://octoverse.github.com/2022/top-programming-languages https://www.jetbrains.com/lp/devecosystem-2021/
https://octoverse.github.com/2022/top-programming-languages https://www.jetbrains.com/lp/devecosystem-2021/
That's a bit pedantic. HCL is not a language you can ever use to write or distribute a program. It's for configuration files. This is almost like saying "YAML is the fastest growing language" few years ago. It doesn't contribute to a healthy discussion.
MIT can very well use the exact same data, where it shows Rust at the top at 50.5% (excluding config languages like HCL).
MIT can very well use the exact same data, where it shows Rust at the top at 50.5% (excluding config languages like HCL).
I've been writing some typescript lately. I had gotten a bit bored about Rust but oh man. The weakness of TS makes me really appreciate the sort of invisible things Rust does right.
I would love to know how you build a language that:
A) is easy to write one off scripts that do a job fast, with minimal thinking and effort. I am thinking of Python and Ruby. For me I can write code with high velocity in these languages.
B) Executes loops very fast and does automatic vectorization
C) Can scale toward large teams, such as that you can do drastic changes with faith that things shall not break at runtime.
D) zero cost abstractions and minimal indirections.
E) predictable runtime performance, no random pauses
F) powerful tooling, such as package manager and IDE integration
A) is easy to write one off scripts that do a job fast, with minimal thinking and effort. I am thinking of Python and Ruby. For me I can write code with high velocity in these languages.
B) Executes loops very fast and does automatic vectorization
C) Can scale toward large teams, such as that you can do drastic changes with faith that things shall not break at runtime.
D) zero cost abstractions and minimal indirections.
E) predictable runtime performance, no random pauses
F) powerful tooling, such as package manager and IDE integration
> A) is easy to write one off scripts that do a job fast, with minimal thinking and effort. I am thinking of Python and Ruby. For me I can write code with high velocity in these languages.
Once I wrap up some other projects, I plan to explore this space a little bit within Rust.
imo the biggest bang for the buck is just having good `#!` support. Probably mid-year I expect to have a Pre-RFC up for single-file cargo packages. See https://github.com/epage/cargo-script-mvs/discussions/15.
A bigger effort is a batteries included, non-zero cost stdlib. I've started writing up my thoughts at https://github.com/ergo-rs/ergo.
For more background on why I think these are important, see https://epage.github.io/blog/2021/09/learning-rust/.
Would love feedback on these ideas and other ways to make Rust easy to use without sacrificing what makes Rust it is.
Once I wrap up some other projects, I plan to explore this space a little bit within Rust.
imo the biggest bang for the buck is just having good `#!` support. Probably mid-year I expect to have a Pre-RFC up for single-file cargo packages. See https://github.com/epage/cargo-script-mvs/discussions/15.
A bigger effort is a batteries included, non-zero cost stdlib. I've started writing up my thoughts at https://github.com/ergo-rs/ergo.
For more background on why I think these are important, see https://epage.github.io/blog/2021/09/learning-rust/.
Would love feedback on these ideas and other ways to make Rust easy to use without sacrificing what makes Rust it is.
> imo the biggest bang for the buck is just having good `#!` support.
Shebangs don't really make sense for AOT compiled languages and I don't know why you would really want one, but you can add `#!/usr/bin/env -S cargo run` to the top of a Cargo.toml file today and it will "work."
I just think the premise of "why didn't you write your last script in Rust" is flawed. It's a systems programming language, if I'm writing scripts I don't really care about the same things - like static typing or meticulous error handling.
It sounds like high effort and low reward imo.
A REPL though (not a true one necessarily - but live-reloading of dynamic rlibs and using dynamic dispatch in place of monomorphization for REPL-builds) would be extremely useful as a workflow tool.
Shebangs don't really make sense for AOT compiled languages and I don't know why you would really want one, but you can add `#!/usr/bin/env -S cargo run` to the top of a Cargo.toml file today and it will "work."
I just think the premise of "why didn't you write your last script in Rust" is flawed. It's a systems programming language, if I'm writing scripts I don't really care about the same things - like static typing or meticulous error handling.
It sounds like high effort and low reward imo.
A REPL though (not a true one necessarily - but live-reloading of dynamic rlibs and using dynamic dispatch in place of monomorphization for REPL-builds) would be extremely useful as a workflow tool.
It makes a big difference when you share a code sample, whether in a blog or on an issue, to have a single block of text to copy/paste including dependency declarations.
It also lowers the barrier for experimentation. I have a directory with probably 40+ cargo-script's for one-off reproduction cases of bugs and it is much easier to work with than juggling multiple files and the overhead associated with it.
It also lowers the barrier for experimentation. I have a directory with probably 40+ cargo-script's for one-off reproduction cases of bugs and it is much easier to work with than juggling multiple files and the overhead associated with it.
> one-off reproduction cases of bugs
I had never considered this case before. I'm going to start doing this!
I had never considered this case before. I'm going to start doing this!
> Shebangs don't really make sense for AOT compiled languages
Tell that to #!/usr/local/bin/tcc -run.
Tell that to #!/usr/local/bin/tcc -run.
I think this is a great idea and I really encourage you to keep going and trying things out.
I'm not sure if C++ and Rust are harder to develop things fast in since I'm not experienced enough with them.
it's the same with haskell, it isn't native for my mind to think from a haskell perspective.
I'm not sure if C++ and Rust are harder to develop things fast in since I'm not experienced enough with them.
it's the same with haskell, it isn't native for my mind to think from a haskell perspective.
I think Kotlin is pretty close to that albeit not satisfying (D) and only satisfying (E) if you use a pauseless GC (which you can do, it's just one command line flag). The pervasive use of type inference gives it a Pythonic feel.
My company has a private tool called hshell that's completely replaced bash for my own use. It uses Kotlin Scripting to provide hashbang script-style development along with a UNIX-like API with functions like cp, cd, ls, find, tar, zip, ssh etc. You can also do things like print markdown to the console and it'll be formatted, and it understands how to draw progress bars from various sources like file copies or loop iterators.
You can depend on libraries by just adding
As it runs on the JVM you also get auto-vectorization, although why you'd want that for one-off scripts I'm not quite sure.
It doesn't have zero cost abstractions. As you note, combining all those features together is rather hard if you want to keep a lightweight scripting feel.
Overall it's pretty nice. I wouldn't want to go back to bash or python, the ergonomics of hshell are far better. I'm not sure what to do with it though, maybe release it as a product (but at what price? is there any demand?). I'm pretty sure I don't want to sign up for open source maintenance duties right now.
My company has a private tool called hshell that's completely replaced bash for my own use. It uses Kotlin Scripting to provide hashbang script-style development along with a UNIX-like API with functions like cp, cd, ls, find, tar, zip, ssh etc. You can also do things like print markdown to the console and it'll be formatted, and it understands how to draw progress bars from various sources like file copies or loop iterators.
You can depend on libraries by just adding
@file:DependsOn("io.ktor:ktor-server-{netty,core}-jvm:2.0.2")
to the top of the file, IntelliJ can give full intellisense and refactoring support for these scripts, they're portable, you can define a CLI by annotating variables and there's a variety of other useful features.As it runs on the JVM you also get auto-vectorization, although why you'd want that for one-off scripts I'm not quite sure.
It doesn't have zero cost abstractions. As you note, combining all those features together is rather hard if you want to keep a lightweight scripting feel.
Overall it's pretty nice. I wouldn't want to go back to bash or python, the ergonomics of hshell are far better. I'm not sure what to do with it though, maybe release it as a product (but at what price? is there any demand?). I'm pretty sure I don't want to sign up for open source maintenance duties right now.
Good questions. Clear, organized. Please share what you find as you compare existing languages.
Regarding (F) -- this is partly about (a) the language's interop story and partly about (b) building a community of people that gets along, get things done, and strikes a balance being independent enough to generate something useful and different while being open to compromising for industry adoption (which often means "slowing down" and stabilizing when the time is right).
(a) There are a lot of great ways to ease editor integration. One is to build/maintain language server / analyzer. See https://rust-analyzer.github.io. Another is to share and maintain a formal grammar.
(b) I've been very pleased with my interactions in the Rust community in this regard. There are certainly many ingredients to mix in ways that make sense for a particular community. In my view, the key aspects are (i) be clear about what your language community stands for; (ii) strike a balance between fairness, transparency, and privacy in how you get there; (iii) build in accountability and feedback loops
Regarding (F) -- this is partly about (a) the language's interop story and partly about (b) building a community of people that gets along, get things done, and strikes a balance being independent enough to generate something useful and different while being open to compromising for industry adoption (which often means "slowing down" and stabilizing when the time is right).
(a) There are a lot of great ways to ease editor integration. One is to build/maintain language server / analyzer. See https://rust-analyzer.github.io. Another is to share and maintain a formal grammar.
(b) I've been very pleased with my interactions in the Rust community in this regard. There are certainly many ingredients to mix in ways that make sense for a particular community. In my view, the key aspects are (i) be clear about what your language community stands for; (ii) strike a balance between fairness, transparency, and privacy in how you get there; (iii) build in accountability and feedback loops
Way to want your cake and eat it too.
If you want the best possible abstraction and developer-scalability, you won't get the best possible performance. In fact, between the quickest start, largest developer-scalability, and best performance, you can only pick one.
If you want the best possible abstraction and developer-scalability, you won't get the best possible performance. In fact, between the quickest start, largest developer-scalability, and best performance, you can only pick one.
> “In C or C++ you always have this fear that your code will just randomly explode,” says Mara Bos, cofounder of the drone firm Fusion Engineering and head of Rust’s library team.
That sounds like a completely valid reason to abandon C++ over Rust.
I mean, what self-respecting programmer that keeps up to date with the trends would use a such a dangerous language that makes code blow up in their face?
That is so '80s.
Well, I am joking, of course, but that comment is hard to take seriously.
That sounds like a completely valid reason to abandon C++ over Rust.
I mean, what self-respecting programmer that keeps up to date with the trends would use a such a dangerous language that makes code blow up in their face?
That is so '80s.
Well, I am joking, of course, but that comment is hard to take seriously.
Yes, in C or C++, code will just randomly explode. That's a completely accurate description.
Once upon a time we had reports from our users that our software had deleted all of the files it could on their C:\ drive. Investigating, we found the code that caused it, something to the effect of:
string rootDirectoryToDelete;
// Set it reasonably:
rootDirectoryToDelete = tempDirectoryWeMadeEarlier;
Want to guess what happened? We had a mix of Emacs and Microsoft Visual Studio 6 developers, and somehow we ended up with a mix of carriage return / line feed in that source file. Both Emacs and the MSVS6 IDE showed those as three separate lines... but the MSVS6 compiler thought that the comment... had no terminator. So it took the assignment on the next line as just being part of the comment.
You bet your ass I worry about code blowing up in my face. I write unit tests to try to protect myself.
I can't tell you how many times whatever the "undefined behavior" was what the code depended on, and fixing it required some severe re-working.
I also can't tell you how often someone thought "const" meant "completely immutable," and then they went on to accidentally modify what the const pointer was pointing at.
Or how often I've had to fix someone else's race condition. Or how often a driver crash has clobbered me.
I came across functionally like this in our code:
int i = 2;
int b = 3;
printf("i = %d, b = %d\n", (i, b));
Want to guess what that does? (i, b) evaluates i, and then ignores it, and returns b. So it basically prints "i = 3, b = [core dump.]" The MSVS6 compiler gave a nice juicy warning on that line that everyone ignored. Yes, using the MSVS6 compiler was dumb, and ignoring the warnings was dumb, but guess what? I'm not in charge of how dumb my co-workers are, or how strict everyone's deadlines are, and bugs like this are actually kind of hard to find in a real code base with tons of problems going on.
I'll take some more predictable behavior, if someone's offering it; yes, please.
Once upon a time we had reports from our users that our software had deleted all of the files it could on their C:\ drive. Investigating, we found the code that caused it, something to the effect of:
string rootDirectoryToDelete;
// Set it reasonably:
rootDirectoryToDelete = tempDirectoryWeMadeEarlier;
Want to guess what happened? We had a mix of Emacs and Microsoft Visual Studio 6 developers, and somehow we ended up with a mix of carriage return / line feed in that source file. Both Emacs and the MSVS6 IDE showed those as three separate lines... but the MSVS6 compiler thought that the comment... had no terminator. So it took the assignment on the next line as just being part of the comment.
You bet your ass I worry about code blowing up in my face. I write unit tests to try to protect myself.
I can't tell you how many times whatever the "undefined behavior" was what the code depended on, and fixing it required some severe re-working.
I also can't tell you how often someone thought "const" meant "completely immutable," and then they went on to accidentally modify what the const pointer was pointing at.
Or how often I've had to fix someone else's race condition. Or how often a driver crash has clobbered me.
I came across functionally like this in our code:
int i = 2;
int b = 3;
printf("i = %d, b = %d\n", (i, b));
Want to guess what that does? (i, b) evaluates i, and then ignores it, and returns b. So it basically prints "i = 3, b = [core dump.]" The MSVS6 compiler gave a nice juicy warning on that line that everyone ignored. Yes, using the MSVS6 compiler was dumb, and ignoring the warnings was dumb, but guess what? I'm not in charge of how dumb my co-workers are, or how strict everyone's deadlines are, and bugs like this are actually kind of hard to find in a real code base with tons of problems going on.
I'll take some more predictable behavior, if someone's offering it; yes, please.
-Wall -Werror is your friend in C and C++ (even -Wextra sometimes). Zero-error policies are generally good. The spec in each language allows a lot of crazy undefined behavior.
Conversely, the rust spec defines... nothing. Rust is specified as "whatever rustc does." That means the compiler is free to be arbitrary on this sort of thing. When there is a spec and there are competing implementations, there will be behavior divergence, and that will create these kinds of issues. Not having a spec can be a good thing.
Conversely, the rust spec defines... nothing. Rust is specified as "whatever rustc does." That means the compiler is free to be arbitrary on this sort of thing. When there is a spec and there are competing implementations, there will be behavior divergence, and that will create these kinds of issues. Not having a spec can be a good thing.
> Zero-error policies are generally good.
I'd love it if you could convince my old board of directors of that. But their first step would probably be to fire everyone who had survived the nightmare, because they "didn't already address it."
I'd love it if you could convince my old board of directors of that. But their first step would probably be to fire everyone who had survived the nightmare, because they "didn't already address it."
Yeah, Rust is better at throwing compile time errors than C, though its defaults still fall kinda short, which is why I include
-Dwarnings -Funsafe-code
in my compile flags. Which is shorter than my C flags: -Wall -Wextra -pedantic -Werror -O2 -march=(arch-of-computer) -pipeI can't follow which bits of this comment are supposed to be serious or joking, but:
> use a such a dangerous language that makes code blow up in their face?
There have simply been too many CVEs relating to memory safety in C and C++ software. It's not the 80s any more and we can't afford that.
> use a such a dangerous language that makes code blow up in their face?
There have simply been too many CVEs relating to memory safety in C and C++ software. It's not the 80s any more and we can't afford that.
There are a lot of places where CVEs don't matter. The HFT firm I worked at groaned over Spectre and Meltdown mitigations, because now our CPUs will be slowed down by not using unsafe behavior. Similarly, I bet a lot of video game folks also didn't like them.
If you aren't connecting to the network or running in any sort of privileged mode, the space of attacks that you need to care about is pretty limited.
Ironically, the answer to a lot of unsafe input in Rust is to crash (if your error handling logic didn't catch it), which is something that you likely care about a lot. Most players care a lot less about corruption of the internal state of your video game than they do about crashes.
If you aren't connecting to the network or running in any sort of privileged mode, the space of attacks that you need to care about is pretty limited.
Ironically, the answer to a lot of unsafe input in Rust is to crash (if your error handling logic didn't catch it), which is something that you likely care about a lot. Most players care a lot less about corruption of the internal state of your video game than they do about crashes.
You can disable such mitigations, which I'm struggling to credibly imagine inside a universe where an HFT firm (that is all about optimisation) would not know about.
The silicon did get slower due to a few mitigations, and in 2018, Intel was thinking about forcing a lot more of them on us in silicon (eg the equivalent of retpolines, but in silicon). The HFT industry and some HPC folks (and I assume some people from gaming) were involved in convincing Intel to keep those mitigations in software.
EDIT: One fun fact here is that AMD never did the unsafe performance optimizations that Intel had to remove from their silicon. Spectre and Meltdown mitigations were instrumental in closing the gap between Intel and AMD.
EDIT: One fun fact here is that AMD never did the unsafe performance optimizations that Intel had to remove from their silicon. Spectre and Meltdown mitigations were instrumental in closing the gap between Intel and AMD.
Corruption of internal state is generally what leads to crashes.
But yes, having worked in service games for over a decade now, clients are treated as untrusted agents regardless. CVEs that result in control over local execution are mostly not interesting. At least for the purpose of maintaining the game; platform holders _do_ care, mostly on fears of piracy.
Galoob didn't cause revenue issues with Game Genie in the 90's. And revenue is the thing what matters.
But yes, having worked in service games for over a decade now, clients are treated as untrusted agents regardless. CVEs that result in control over local execution are mostly not interesting. At least for the purpose of maintaining the game; platform holders _do_ care, mostly on fears of piracy.
Galoob didn't cause revenue issues with Game Genie in the 90's. And revenue is the thing what matters.
My point is, I find the whole C++ bashing bizarre. Not to mention the never-ending Rust evangelism.
Rust is a good language and tracking memory access and ownership is something that's not always easy to do in C++, even with smart pointers.
For some projects, like browsers, that's a big deal, for others, like games, not so much.
But, it's not like you can't do dumb things in Rust. You can explode your code in any language you desire. Your skill is the only limit.
Rust is a good language and tracking memory access and ownership is something that's not always easy to do in C++, even with smart pointers.
For some projects, like browsers, that's a big deal, for others, like games, not so much.
But, it's not like you can't do dumb things in Rust. You can explode your code in any language you desire. Your skill is the only limit.
>For some projects, like browsers, that's a big deal, for others, like games, not so much.
Cheating in games is a big problem, and lots of money is spent addressing it, not to mention techniques which are barely distinct from spyware which cause performance reductions on the side.
A lot of that cheating relies on bog standard memory bugs which game devs don't care about, apparently.
Cheating in games is a big problem, and lots of money is spent addressing it, not to mention techniques which are barely distinct from spyware which cause performance reductions on the side.
A lot of that cheating relies on bog standard memory bugs which game devs don't care about, apparently.
> I find the whole C++ bashing bizarre. […] You can explode your code in any language you desire
Some of us have spent decades working as sysadmins, getting woken up in the middle of the night to deal with whatever the latest CVE is... Do kids these days even know about codered, heartbleed, etc?
Some of us have spent decades working as sysadmins, getting woken up in the middle of the night to deal with whatever the latest CVE is... Do kids these days even know about codered, heartbleed, etc?
Take a look at this and you'll see it actually just randomly blows up :^)
https://kristerw.blogspot.com/2017/09/why-undefined-behavior...
Another "funny" one: https://www.reddit.com/r/cpp/comments/10yk8hk/ub_clang_decid...
When you're working with software controlling lithium batteries, things literally blowing up in your face because of code mistakes are an actual concern.
Things figuratively blowing up in your face are a concern even when not working on batteries.
Things figuratively blowing up in your face are a concern even when not working on batteries.
I just wish it was simpler. I never saw it in its infancy, but from what I can gather, it seems a huge amount of bloat was added to the original design.
I'm biased as a Rust fan, but I don't think this is accurate. I think this impression comes from people who don't know Rust reading the release notes and assuming that the rate of new features must mean the language is full of old legacy junk that no one recommends using anymore. But there are actually very few things like that in standard Rust. (The old `try` macro and the `ref` keyword are two examples. std::sync::mpsc is maybe another.) A large portion of the changes have been fleshing out APIs and removing limitations, which arguably makes the language less complicated over time. "Nonlexical lifetimes" and "match ergonomics" are two examples of this, which each took a lot of work.
Thanks to you and the other commenter. It seems my perception of the timeline is indeed incorrect, although I'm not sure my view of its complexity is. I have found it difficult to dive into but want to give it another whirl here at some point.
There's definitely a learning curve, no doubt about that. I usually advise learners to expect to read a book. It doesn't have to be The Book, and there are several other good ones to choose from, but expect a book. For most people, learning from examples and compiler errors isn't the way to go.
If you happen to be coming from a C++ background, here's a shameless plug for my own intro video :) https://www.youtube.com/watch?v=IPmRDS0OSxM
If you happen to be coming from a C++ background, here's a shameless plug for my own intro video :) https://www.youtube.com/watch?v=IPmRDS0OSxM
Bloat like?
Bloat is probably the wrong word, but I meant bloat in terms of complexity, at least from my perspective in terms of how easy it is to learn.
I've programmed in Rust since 0.7 and I can assure you that the Rust today is the leanest, easiest to learn version of the language.
Since 1.0 Rust has added ability to use arrays larger than 32 elements. That's not bloat, that's a fix of an embarrassingly large TODO left in 1.0.
Rust added a new module system, which most people find easier to use than the original one. The new one technically does more, but these are things that everyone expected it to do anyway (e.g. in Rust 1.0 use of `std` in code worked only in some files, sometimes, because reasons. Now it works in every file, even though technically it's a more complicated name lookup).
Rust has added a new borrow checker. The implementation is waaay more complicated than the original scope-based one, but the result for the end user is that it mostly just works. In Rust 1.0 lots of borrowing didn't work for dumb reasons. You used to have to declare variables precisely in a reverse order of their destruction, or the code wouldn't compile. You often had to add extra {} around lines of code that mutated collections, because the simplistic borrow checker didn't understand when the mutation ended.
Even async, which itself is a big new feature, simplified networking code a lot. I've written a network service in Rust before async, and it was a pain, and run-time overhead, to deal with ownership in callback closures that required manual reference counting and didn't allow references. Async in Rust still has its quirks and limitations, but Rust 1.0 had all of them, and then some more.
Most importantly, Rust error messages have massively improved since 1.0. Things that used to be gotchas where people were getting completely stuck (such as needing .as_ref() on Option) are now pointed out by the compiler.
The compiler is now much faster, and generates better code. Rust has matured, and almost everything it has added since 1.0 should have been in 1.0.
Since 1.0 Rust has added ability to use arrays larger than 32 elements. That's not bloat, that's a fix of an embarrassingly large TODO left in 1.0.
Rust added a new module system, which most people find easier to use than the original one. The new one technically does more, but these are things that everyone expected it to do anyway (e.g. in Rust 1.0 use of `std` in code worked only in some files, sometimes, because reasons. Now it works in every file, even though technically it's a more complicated name lookup).
Rust has added a new borrow checker. The implementation is waaay more complicated than the original scope-based one, but the result for the end user is that it mostly just works. In Rust 1.0 lots of borrowing didn't work for dumb reasons. You used to have to declare variables precisely in a reverse order of their destruction, or the code wouldn't compile. You often had to add extra {} around lines of code that mutated collections, because the simplistic borrow checker didn't understand when the mutation ended.
Even async, which itself is a big new feature, simplified networking code a lot. I've written a network service in Rust before async, and it was a pain, and run-time overhead, to deal with ownership in callback closures that required manual reference counting and didn't allow references. Async in Rust still has its quirks and limitations, but Rust 1.0 had all of them, and then some more.
Most importantly, Rust error messages have massively improved since 1.0. Things that used to be gotchas where people were getting completely stuck (such as needing .as_ref() on Option) are now pointed out by the compiler.
The compiler is now much faster, and generates better code. Rust has matured, and almost everything it has added since 1.0 should have been in 1.0.
>"> “In C or C++ you always have this fear that your code will just randomly explode,”
No I do not. I have a fear of sectarian fanatism where each sect is trying to force their way of doing things and declaring the rest being evil.
No I do not. I have a fear of sectarian fanatism where each sect is trying to force their way of doing things and declaring the rest being evil.
Obligatory xkcd[1]
[1] https://xkcd.com/1102/
Where in the article it says that it's the fastest growing language?
Considering it can seen on slug, was probably the original title.
The title of the article is actually, "How Rust went from a side project to the world’s most-loved programming language" .. which is so annoying.
"Most-loved" cannot be measured, it's so subjective. Why couldn't they have just said, "fastest growing" or something else? Does everything from media have to be designed to grab eyes, even out of the MIT Technology Review for godssake?
"Most-loved" cannot be measured, it's so subjective. Why couldn't they have just said, "fastest growing" or something else? Does everything from media have to be designed to grab eyes, even out of the MIT Technology Review for godssake?
"Most-loved" has definitely been measured. It's a direct finding from StackOverflow's developer survey.
https://stackoverflow.blog/2020/06/05/why-the-developers-who...
https://stackoverflow.blog/2020/06/05/why-the-developers-who...
There is a C ssl library and a rust ssl library, which one do you choose?
There is also a http library I C and rust , which one do you choose?
If C ones are battle tested, I will not choose rust for a simple reason, software is error prone in nature, and believe certain practices will fundamentally change that is just selling snake oil.
There is also a http library I C and rust , which one do you choose?
If C ones are battle tested, I will not choose rust for a simple reason, software is error prone in nature, and believe certain practices will fundamentally change that is just selling snake oil.
Tony Hoare: billion dollar mistake adding NULL to algol in 1965
Graydon Hoare: cracks knuckles in 2006
Graydon Hoare: cracks knuckles in 2006
It is still missing some alternative rust-written rust compilers.
sashank_1509(13)
I see a humungous amount of astro turfing for rust adoption on hn.. I wonder why its so damn important to love rust..
If someone's paying folks to shill Rust, then they owe me money!