Rust went from side project to world’s fastest growing language
technologyreview.com
technologyreview.com
"Oh yeah? If X is so good, why aren't there any real software projects written in it?" etc.
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]."
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-...
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.
>> 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?
https://goodmanwen.github.io/Programming-Language-Benchmarks...
compared to what rust has to offer, compared to C and CPP, this is truly awesome.
The Rust fanatics have VERY thin skin if the language they hate gets any upward-adoption news.
Security is an especially big one for lots of systems
"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.
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)
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
I’m referring to systems software (operating systems, browsers, runtimes, backends) where formal verification is not normally used.
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.³
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 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.
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.
How is most generic comment under HN Rust topic shocking?
It's almost the opposite effect of all the comments that appear on Electron projects regarding bloat.
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 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.
also, possibly related, isn't it strange you see almost no more haskell posts here these days?
The URL slug shows the old title perhaps.
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!
https://www.openhub.net/languages/compare?language_name[]=ru...
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.
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)
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!)
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
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.
Domain Modelling Made Functional
Totally agree: i think folks dont realize F# is modernized OCaml and this is approximately a typed Lisp semantically. Very useful.
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.
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....
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.)
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?
But I'd assume that most are just used by their creators.
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.
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?
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.
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.
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.
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".
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).
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.
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.)
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.
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"
As far as I know, the Rust developers consider performance worse than C a bug.
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).
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.
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.
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.
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/...
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.
> 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-...
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.
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/...
"Milli benchmarks are not really hard
Micro benchmarks are challenging, but OK
Nano benchmarks are the damned beasts!"
Slide 19
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.
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/...
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".
> … 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/...
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/benchmarksgameOn 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.
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.
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.
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).
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.
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?
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.
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).
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.
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.
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.
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)
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". :-)
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.)
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++).
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
I can't tell if this is sarcasm or not.
https://octoverse.github.com/2022/top-programming-languages https://www.jetbrains.com/lp/devecosystem-2021/
MIT can very well use the exact same data, where it shows Rust at the top at 50.5% (excluding config languages like HCL).
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
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.
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.
Tell that to #!/usr/local/bin/tcc -run.
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.
I had never considered this case before. I'm going to start doing this!
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.
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
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.
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.
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.
> 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.
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.
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.
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.
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.
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.
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."
-Dwarnings -Funsafe-code
in my compile flags. Which is shorter than my C flags: -Wall -Wextra -pedantic -Werror -O2 -march=(arch-of-computer) -pipeThings figuratively blowing up in your face are a concern even when not working on batteries.
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.
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.
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?
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.
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
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.
"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?
https://stackoverflow.blog/2020/06/05/why-the-developers-who...
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.
Graydon Hoare: cracks knuckles in 2006