If by casual user, you mean the 95% case of a back-end developer whose main job is pulling data from various sources, performing operations, and placing that data elsewhere and/or displaying it to an end user: nothing, really.
Rust excels at performance, but the bottleneck in modern web apps is going to be IO, whether that's loading data from a database or from a third-party API you're integrating with. Rust excels at correctness, but your errors are going to come from bad data and system outages which require manual intervention anyway. Rust excels at security, but if you're using a GC language running on a Docker container on an ephemeral cloud instance, the kind of security Rust provides isn't a likely attack vector for you.
All that being said, Rust is a great language! It just has its niche, and that niche is not the typical web-dev back-end work that most developers do these days. As others have said, you'd use Rust in the same situations you'd use C++: building a database, building a web server (like nginx), etc. If you're just building a web app that talks to a database and serves HTTP responses, stick with Python/Ruby/Go/PHP.
This is true in some senses, but also, response latency isn't the only thing a web application does or is evaluated by. Many applications have, for example, background jobs, that do arbitrarily complex processing outside of the request/response cycle.
Additionally, people who write web services in Rust talk about decreased memory usage, consistent memory usage, and lower CPU usage. In a cloud context, that can translate directly to revenue saved, by spending less. If that tradeoff is right for you depends on a variety of things, of course. "speed" isn't the only relevant metric that you may want to optimize for.
You are looking at ~5mb container vs 200+mb if you did a jvm based container.
It's probably overkill for most applications and companies, but it's something to keep in mind if you need fast scaling for cheap.
Not to mention you can use GraalVM native-image to compile to a binary directly, in which case it'll be even smaller.
Yeah, for sure -- I deal with a web app that does complex, time-consuming analytics in data pipelines with Python, and Rust could help a lot with improving some of the complex calculations. But again, that's more using Rust as a C++ replacement rather than looking at replacing, say, the Python-Flask frontend that serves up the results of those analytics.
> Additionally, people who write web services in Rust talk about decreased memory usage, consistent memory usage, and lower CPU usage. In a cloud context, that can translate directly to revenue saved, by spending less. If that tradeoff is right for you depends on a variety of things, of course. "speed" isn't the only relevant metric that you may want to optimize for.
It'd definitely reduce costs, but yeah, be sure to get a full picture here from a business perspective. Engineers love to optimize AWS costs, but it isn't appropriate in a lot of situations. In my case, I'm paying a nontrivial 5-figure monthly AWS bill, but if my company's AWS costs went to $0/month... it wouldn't move our death date, and it wouldn't change our valuation. This is especially true if there were any loss in developer productivity/feature releases. I would gladly double my AWS bill if I could get features out even 20% faster, though that's not how it works, obviously.
This means that you don't accidentally forget a null check (or a catch block) and, in my experience leads to software that is a lot more robust.
Even if all it is doing is pulling from a database and munging it into JSON.
_ => ()
to avoid having to handle it, but at least that's easy to pick up on in a code review.
Rust's error handling might be great for people who are used to exception based error handling but it is a joke compare to railway oriented programming in Fsharp or any ML lang that supports |>.
In practice, every time I've tried out Ocaml, I've bounced off _hard_. The standard library is very limited and filled with cruft (stdlib regexes being a notable example), so users very quickly need to start understanding the alternatives. There's little in the way of good intermediate documentation, so once you've figured out how recursion works, it's often quite hard to figure out more practical questions, like when it makes sense to switch to refs and imperative code for a problem. There's also not a lot of "practical" libraries - I wanted to write a small web service recently to organise house chores, and I figured I'd need a decent datetime library (with support for juggling timezones), some way of interacting with sqlite, and a basic web server. The web server situation was okay, but the only SQL library I could find was 80% ungoogleable sigils with minimal documentation, and I couldn't find a single datetime library that has a concept of instances that could be interpreted in different time zones.
In contrast, Rust has a clean (albeit minimal) standard library, with a lot of good pointers to well-maintained third-party libraries; it has plenty of documentation ranging from the beginner guide to the Rustonomicon; and there's a lot of stuff happening in the ecosystem that you can already start relying on. Like, if you're coming from Java or Python you might have to lower your expectations somewhat, but you can still have expectations of _something_, which is not my experience with Ocaml.
I think I need to try out F# more - my impression is that there's at least an existing C# ecosystem there which helps with a lot of the practical issues - but so far I've been really disappointed by my experiences in ML-land. There's so much I want to like - I'm really excited about the new effects work that's happening, for example - but the ecosystem as a whole just doesn't seem that usable for practical things unless you already know what you're doing, or unless you're prepared to build all the stuff you need from scratch à la Jane Street.
So actually, in practice, I find myself much more productive in Rust, despite coming from a Python/Java/JS background. The memory management stuff turns out to be pretty easy to pick up, and having a strong ecosystem means that I've generally got the tools I need at my fingertips.
If I do them in Rust, I would need to build from scratch and I rather not, as that isn't my focus.
Besides F#, there are also Haskell, Scala, Kotlin.
Java and C# are also getting there, even if a bit slowly, and compromised by backwards compatibility.
Jane Street's Core has a good timezone support (the thing you need is pair Date.t * Time_ns.Ofday.t). sqlite3-ocaml [1] seems reasonably documented.
With that said, it's okay if there isn't much in it for you. If it doesn't sound useful for your current use cases, that's okay. Don't use it. Use things because they are interesting and fun or because they make your life better. Don't feel the need to use it just because it's on The Orange Site a lot.
It's probably not a good first language, but neither was C++: that's not its niche.
Actually both C++ and Rust tend to make heavy use of reference counting via `std::shared_ptr<T>` and `Rc<T>/Arc<T>`, respectively. Personally I think that while Rust's borrow checker is nice for some cases and does encourage fast/efficient memory usage, it's also overkill vs automatic memory management for even most system or real-time programming. Especially as compilers get better and can remove 90% of the reference counting spots.
As esteban says, these types do get used more often in async code, which I don't write a ton of at the moment.
But more importantly, I think that if a beginner tries to use arc/rc to "get around the borrow checker" it introduces even more pain. It's not a beginner's tool, it's a possible misleading path. I left a comment a few years back with a practical example here; while the root cause isn't refcounting, look at how much ceremony they add https://news.ycombinator.com/item?id=24992537
If we were talking about clone, however, that would be a different story: clone is often a great tool for beginners who are struggling with a design that fits into what Rust wants.
And even then, the comment didn't qualify as "beginner code" or "expert code": it said that Rust programs generally "make heavy use of reference counting" and that's simply not my experience, nothing more, nothing less. Not only with my own code, but code I see others write, and libraries that I and others use. YMMV, as always.
Also it’s just plain fun sometimes. I love expression based syntax where you can assign to an if or have a block result in a value. It just feels delightful. The standard library is very constrained but within those constraints it has a lot of wonderful depth. Functions like split_once or unwrap_or_else are delightful to use. It gives me that same feeling as Ruby where the language feels designed to have you enjoy writing code. The language has all of the requisite tools I want to model data structures including tuples, structs, and enums. It’s great! Try it out and see for yourself
In languages without spread operators (like java), immutable objects are quite clumsy to work with: I want this same object but these two fields changed (like the replace method on python's named tuples, but those are also annoying...). But with mutable objects, everyone can mutate: chaos. Rust gives you the mut keyword, structs are immutable by default.
Ever wanted to implement a method on a class in another library that just used the public API? Just make your own Trait in rust.
Ever wanted to make sure that someone would call `close()` on your implementation? Ever wanted to make sure that no one would use the object afterwards? That's garbage collection of a resource that isn't memory, most GC languages won't manage that for you, but the borrow checker will.
Pattern matching, algebraic data types, expressions and statements distinctions, an excellent build system, procedural macros, no null, no exception handling, good type inference; none of these are new or unique to rust, but lots of languages lack a few to many of them.
But yeah, some times I don't want to decide between monomorphisation via generics, or heap allocating for dynamic dispatch. Some times I just want a JIT and a garbage collector to take care of that for me. But that is another thing rust might give you: a newfound appreciation for what you have.
Pattern matching (for records) is already a preview feature.
A feature of modern computing is the use of very low power systems (I programme mostly for Raspberry PI - not very low power) and/or systems run on "pay as you go" platforms which can scale hugely.
Rust is very efficient at run time. (Not at programming time nor compile time) so is very useful in these cases.
A counter example, from my life, to illustrate: I ran a mail server for a group I was involved with. I spun up a VPS and Mailman. (Mailman v3 is built on Django/Python). I had to double the capacity of the VPS as 500MB of memory was not enough to install and run Mailman (I think the problem was at install time, but that made very little difference). The cost of my mail server doubled because of the inefficiency of the Django/Python framework.
Django is very efficient at programming time, but is resource hungry. The original Mailman ran in 40k, the "modern" version was not usable on a platform with 500MB.
For me it was no biggy. One server, $10 not $5 a month. Mēh! But if that were a million instances.....
So with all the progress in computers getting more powerful the actual instances we use are getting weaker (for very good reasons). A language like Rust can be very helpful in this case.
(On the Raspberry Pi I use Rust for realtime control of audio processes)
As much as I like Elixir, it wouldn’t do as well running within Sandstorm as something written in Rust.
That being said, there are also downsides - apart from the steep learning curve, compilation is pretty slow and the language itself isn't as good as some others for prototyping - if you make something simple and want to go fast, then maybe TypeScript will do a better job, despite its numerous problems.
Rust is more about robustness and correctness (and performance of course). If these are not appealing to you, then sure some other languages like Java, Go, C#, TypeScript or others can do the job.
I’ve used a bunch of common languages, Python, JavaScript, Typescript, PHP, Bash, Go etc. Not so common languages such as Haskell.
My first choice for personal projects is now Rust.
The memory/borrow checking to me is just a nice benefit I get from using Rust, I don’t use Rust for the borrow checking.
My main reason for Rust is while it’s not as high level as say Java/Python etc I find it is still at a nice level to work with and can be far more expressive with the enums, traits and generics.
The second big reason I use it is my programs end up fast and efficient with little effort.
The third reason is I can get tiny statically linked binaries that just run anywhere with no dependencies.
Reasons two and three mean I can host my applications on the cheapest, most minimal resources available and still outperform other languages on more expensive hosting. Currently my choice is to stick the binary in a Docker image which ends up sub with a sub 10mb docker image then deploy on the smallest 128mb AWS lambda and pay fractions of a cent to host. Services that need to be long running go on the smallest $5-10 vps’s .
The borrow checker can be a pain however I find the compiler error messages really helpful in it often tells you what you should do to fix the problem with plain English error messages and code suggestions.
On middle range hardware, it appears to be the moment for a coffee pause, although it has definitly gotten better, specially with updated reachability metadata.
---
I'm not sure I agree with the article's premises. Rust can be difficult, yes, but it can also heighten developer productivity above other languages. In Go, I'd have to worry about whether I checked for exceptions via `if err != nil` everywhere, while with Rust, I can depend on the compiler telling me if I haven't done so exhaustively, via the Result type. Same for having algebraic data types or, well, generics in general.
I will also push back on other commentors here saying Rust is not good for web apps and APIs, and I have found that to be the opposite of true. I read Zero To Production In Rust [0] (a great book by the way, all about creating a web API with actix-web and Postgres) and deployed an API that has not gone down a single time since deploying near the beginning of this year. It's as ergonomic as (and sometimes even more so than) any NodeJS or Go API I've made (as even though Rust doesn't have function overloading, actix-web and others have some macro magic they do behind the scenes to make it appear as if it does), and there were very few times I had to contend with the borrow checker. If there had been and if I were really going for speed, I would also have cloned everywhere that was needed.
When I write something in Rust and it compiles, I can depend on it to work, and to continue working. At the end of the day, use the tool that makes sense for your business, but I don't think Rust was necessarily a bad choice based on my personal experience with it.
[0] https://www.zero2prod.com/
---
IMO the strengths of the language are not a deal-breaker for a casual user (e.g. someone writing CRUD or line-of-business applications)
But doing a rewrite requires Rust programmers and they hard to hire.
Rust is quickly growing into Golang and Java's space for web services.
My startup uses Rust in production for our web APIs, and we're really happy with it.
[1] You'll probably need to spend a few hours learning the language basics, but it's really easy at this point with the docs and best-in-class compiler error messages.
But, before you can make anything meaningful with a language, you have to first make many toys. That's the rationale for using it in cases where there are better alternatives. (To make you comfortable using it when there is a need for it.)
Because I already know Rust, and prefer it as a language generally, it’ll be my default choice, just like you have your default choice. It works well for many cases in the backend, but not all of them, like lots of technologies. If you don’t find a compelling reason to switch, you shouldn’t!
For me the biggest win with Rust is the performance that I can get out of it, which is irrelevant in most cases. If you work on a problem that requires extreme single node performance then you can learn Rust instead of learning C++. This is probably less than 10% of the use cases people use programming languages for. As far as teaching juniors: I had great success with Python, yet, a lot of foot-gun situations. With Rust I am not good enough to mentor our junior devs, so we learn together. It goes very slowly.
Rust is genuinely only useful for the niche application of a desktop application, that doesn't reach low level, but you need a bit more fine grain controls than C# or another higher level language will allow. For example, a web browser is like the ideal usecase for Rust, and it makes sense, since that's really where it's got most of it's teeth with Mozilla.
I personally don't see why you would do something like Grep, in Rust, when C#, Python, Go, exist. But I do see like Unreal Engine or again, Firefox/webbrowser in Rust being nice.
If you tried this in python it would probably take hours to scan through something that ripgrep does in a few seconds
Maybe you don't know what you're talking about, despite coming across as certain of yourself.
If you respond, please provide instructions to reproduce your measurements for a Linux machine.
Why do you even have to write one in the first place? If C# is such a natural choice, why hasn't it already been done?
My testing will be on my Dev VM, in a WSL container on ubuntu 22.04, targeting a built linux kernel. With powershell from the Microsoft blobs they ship for linux. And Ripgrep from just Apt Install Ripgrep. With 5 warmup cycles for each.
Are you talking about findstr? If so, I'm not sure that's available on Linux. So it doesn't seem like a viable grep to me. If the program you want to be a grep only runs on Windows, then that isn't really viable.
Also, Windows file system operations tend to be quite a bit slower than Linux.
Also, where is the source for findstr?
But I don't think it's the fault of C# and I think it's the fault of some poor coding on redmonds side, and very good coding on your side. And since I have to make up 12 hours tomorrow at work, but have zero tickets. I'll probably go in and write a Grep utility in C# and I think I can get similar speed to the Rust implementation.
C# is also cross platform as of a couple years ago, as well as is powershell. So my testing was running Powershell on linux against the newest linux kernel source code + the build artifacts.
PCRE is absolutely a competitor to Rust's regex crate and it makes sense to compare them.
If all you're doing is measuring the time it takes to find `foo` or `\w+_foo`, then the specific regex engine being used is just an implementation detail.
I'm not saying that using --pcre2 is wrong. It is certainly a useful comparison. But using the default regex engine when the task is "measure a grep" is certainly not wrong either.
There are very good reasons to explain this state of affairs.
C# is not something I have a lot of experience with. I don't spend time with Windows-only technologies. C# may technically work on Linux these days, but I don't know of any popular general purpose CLI tooling built with it that works on Unix systems. Why is that? My suspicion is that there are good reasons for it. But if there aren't, then there is a market opening waiting for folks to plow forward.
Basically, I think you are wrong on multiple levels. I think you both under-estimate the difficulty of writing a fast grep and what exactly it takes to do it, and I think you're completely wrong about when Rust is useful. You completely neglect the safety aspect of it, and seem to believe it is not on even footing with C or C++ when it comes to performance. But it most certainly is, in general.
> But I don't think it's the fault of C# and I think it's the fault of some poor coding on redmonds side
Making baseless assertions feels like a pattern that is forming in your comments. Where is Redmond's code? Can you read it and link to me the parts that are "poor"? If not, from whence comes the accusation?
And if you insist with your interpretation of reality, then it follows that I therefore must be a good coder. And if a good coder says to you, "I do not know how to write a fast grep in Go, Python, Perl or Ruby," then why don't you take them seriously?
As for the safety aspect. Can you tell me what Rust means by "Safety"? Alot of Rustacians throw it out, but it really only means "No Undefined behavior". It can help hint at issues, but as someone who writes C code day in and day out, a proper coding technique like SESE can prevent all the issues Rust prevents, and a Static Analyzer like SAL goes far and beyond it. And then with all the icky runtime checks Rust adds, you can't get that in the Kernel, you can't get that "for free". And speaking of reversing your code, it throws in your path names, your file names, and information about the code into each of these. It's definitely not safe opsec wise for a dissident in a dicatorship or an activist!
You also seem to claim C# is "Windows only". Neither C#, nor Powershell, are "Windows Only". C# can run on just the same targets Rust can. WASM, Linux, Windows, etc. You said I wasn't talking about things I was knowledgable on, but despite multiple "hints" on that it's not "Windows Only", you don't seem to want to accept that. It's been the case for years. Being that stale with tech would be retire or fire territory, or just an indicator of incompetence.
And I never said you were a good coder, I said you did a decent job writing RipGrep based off of performance. I personally think from your comments that you have a very small amount of experience with Language design or low level programming, and would not hire you and would put in my review "Does not take hints, is very rude and stubborn."
You call my claims baseless, I went and did testing on the PS commandlets and said they were not fast. I have a program i'm testing right now which matches RG in performance. I'm going to name it "RipGrep But Not Ass". I'll have it on github for you whenever I get the time to finish it. Then you can "Analyze the source code". This conversation is dumb, and you are honestly one of the worst people i've encountered in the coding community.
It's important to understand what is being measured. It's not required in the strictest sense, but I am after understanding and without the source, that is difficult. If it doesn't take an "Einstein," then surely you can provide a link either to the source of whatever program you're measuring or some simple instructions for discovering it?
> a proper coding technique like SESE can prevent all the issues Rust prevents
Sigh... So many words on the Internet have been spent on this and related topics, and I do not have the energy to repeat them. If the only education you have on the matter are the words of "Rustacians," then there is plenty more for you to seek out. Maybe start here: https://security.googleblog.com/2022/12/memory-safe-language...
> And then with all the icky runtime checks Rust adds
The only runtime checks ripgrep omits are a few bounds checks deep in the regex engine, and even that gains a 5-10% performance improvement in only some workloads. It would not meaningfully impact ripgrep's overall performance. And yet, ripgrep is faster than GNU grep straight up in many/most cases, which is written in C and lacks your supposed "icky" runtime checks.
> And speaking of reversing your code, it throws in your path names, your file names, and information about the code into each of these. It's definitely not safe opsec wise for a dissident in a dicatorship or an activist!
I'm not aware of any official Rust materials or anyone with any credibility advocating otherwise.
> You also seem to claim C# is "Windows only".
I caveated all such mentions, yet, you seem to ignore them.
> Being that stale with tech would be retire or fire territory, or just an indicator of incompetence.
OK, wow, this conversation has gone to another level. Not really sure what to make of it. I am not retired but gainfully employed. Perhaps I am incompetent, it is not for me to say. Much of the code I have ever written is public, so perhaps you can judge this quality yourself. And if you do, I would love to have any learned critique.
¯\_(ツ)_/¯
> And I never said you were a good coder
I didn't say you did. I specifically and carefully drew an inference, but one you clearly dispute.
> I personally think from your comments that you have a very small amount of experience with Language design or low level programming, and would not hire you and would put in my review "Does not take hints, is very rude and stubborn."
Perhaps you confuse skepticism with rudeness. I am here challenging your claims, of which you have provided zero evidence, but for which I have both published code and published analyses that dispute them. I am glad, though, that my employment does not depend on the whims of random anonymous denizens of the Internet.
> You call my claims baseless, I went and did testing on the PS commandlets and said they were not fast. I have a program i'm testing right now which matches RG in performance. I'm going to name it "RipGrep But Not Ass". I'll have it on github for you whenever I get the time to finish it. Then you can "Analyze the source code".
I'd be happy to analyze it and provide commentary, welcome or not.
> This conversation is dumb, and you are honestly one of the worst people i've encountered in the coding community.
I'm sorry for having troubled you so. I don't mean to come across as rude, although I can see how you might take it that way. I am not really a fan of commentary that states things so certainly but which are contrary to what I perceive to be reality. In so doing, I presented my view of reality and have yet to see a competing version that I can engage with. It is precisely because of that ignorance that I have asked for something that I am able to engage with. I cannot, without expending more resource than I care to, engage with something that is Windows-only or requires a Windows environment to test in. I did not mean to say that what you were doing had those requirements, but meant to merely state what my requirements for engaging were. The point of being clear is not only for me to avoid wasting my time, but for you to avoid wasting yours.
But, I would be happy to do so on my Linux machine if it's possible and update my version of reality. Surely, given that I know little of C#, there is much for me to learn. I note though, that your original comment mentioned several languages other than C#, and my original response did not call out C# specifically. The reason being, of course, that I acknowledge my ignorance of that technology. (And have done so in this conversation before this comment.) Even at the risk of labels of incompetence or staleness from HN commentators.
There's tons of web applications that don't write backend logic in C or C++, but in a GC'd, possibly dynamically typed language.
In Python's case the pull was different in quality, it was about a higher level more expressive language that could get more done faster compared to the estabilished corporate/enterprise languages.
For backend web dev: Skip it. I prefer Python/Django.