> I like to make silly things, and I also like to put in minimal effort for those silly things. I also like to make things in Rust…
I think this part is perhaps the silliest part of a very silly article. If you really like to put in a minimal effort then why on earth would you use Rust? If you want efficiency, memory management and a compiled modern language just use Go. Then you won’t even need anything but the standard library for what you want to do. Or… use Django as you suggest?
Yes, yes we use Rust in production because we thought it would be easier (well safer) to teach to interpreted language OOP developers than c/c++ but why on earth would you ever use it for the web unless you are a member of the cult?
I am a fan of Rust for systems programming, but so many people are using Rust for things that are nothing even remotely close to systems programming. So many projects you see being written (or rewritten) in Rust are projects where I just think 'wait, why can't this just have a GC'? And then you look at the code base, and it's all Arc<Mutex<RefCell>>s, and you can't help at marvel at this, since that's just GC, so what's the benefit of Rust here, exactly? (Don't @ me, ARC is GC.)
I think a lot of what people actually like about Rust, to be honest, is that it's essentially an ML language masquerading as a C-like, with a stellar packaging and tooling story. What people fall in love with is the rigorous static typing, the Option monad, the exhaustive enums (which are just sum types in disguise), the traits (type classes in disguise), the borrow checker (a half-way house to immutability) etc. People will brag about Rust's memory safety, and then you find out that they don't really know how lifetimes work, they just .clone() or Arc<Mutex<RefCell>> everything. Which is totally valid, but Rust is hardly necessary for that.
Rust is great, but - heretic idea - not literally everything needs to be in Rust. Go try Ruby on Rails for a while! Or - if Rust has whetted your appetite for more functional styles - Phoenix on Elixir! Yes, it's not quite so blazing fast, but - let's be honest here - you're not going to be getting billions of requests per second on your hobby website where you write about taking apart Amigas. It's OK! She'll be right.
I'm just really leery of using languages that don't have a clear separation between immutable and mutable state. Having it in Rust catches so many bugs.
I also want to write code in languages where you don't have to engage in bad software engineering practices to get optimal performance. That usually means aggressive inlining, something that Rust excels at.
edit: the other thing I wanted to mention is that rust's features cause dependencies to be pretty high quality.
If I pass in a slice of something, I'm no longer worried that something ten layers down will change it.
Error handling is explicit and panics are rare, so I'm not worried that dependencies will start throwing exceptions after an update. (This is the reason functions should indicate errors in type signatures—a better ecosystem.)
ADTs mean dependencies represent fewer illegal states internally.
It's just really nice to write code where the bugs are a couple levels up from bullshit like this.
I think this is a legit sort of reasoning, but in an interesting way it's something where OCaml could fill the gap. It has its ergonomics issues, but I think the issues are basically the same/worse in Rust (except I guess Rust's macro system is better).
I say this as a Rust enjoyer, but I take the pain because I _really_ want what I'm working on to be fast.
I like OCaml a lot as a language, but the tooling is very, very poor by modern standards. Poor enough that I think it’s a total blocker on wider adoption.
OCaml is definitely something I'd consider using if I didn't already live and breathe Rust :)
I use Rust often for things that aren't possible in other languages, so I also use it for things that are possible in other languages. (Though I used Python for a production and an art project recently -- with uv it's quite nice.)
> What people fall in love with is the rigorous static typing, the Option monad, the exhaustive enums (which are just sum types in disguise), the traits (type classes in disguise), the borrow checker (a half-way house to immutability) etc.
I feel like I say this every time this sort of discussion comes up, but I still think that there's a space for a higher-level language with most of what people like from Rust that has a (tracing) garbage collector and is slightly more relaxed with trying to design a way around every marginal heap allocation. Most of the time I bring this up, someone will suggest something like Swift or OCaml, but I think the part people miss is how even despite all of the complexity that comes with being a systems programming language, Rust really goes out of its way to try to be developer friendly despite that.
Yes, it's a meme that Rust programmers are zealous evangelists and want to rewrite the world in it (which is a bit of an exaggeration in terms of lumping all Rust enthusiasts into that group, but there's certainly an element of truth in it), but no one seems to talk about how _weird_ of an idea it is for a language notorious for having a terrible learning curve to be so popular with people perceived to be lacking real-world experience with the domain. How did a language that's supposed to be so hard get popular to the point where people view its fans as pushing it aggressively? You might chalk some of it up to marketing, but I think people undervalue how much effort is put into the little details in Rust to try to make it more approachable, like error messages, standard library documentation, first-class support for all major platforms, and high-quality introductory materials (e.g. both the original and rewritten The Rust Programming Language book, Rust by Example, Rustlings). I don't think the same experience is there if you want to use Swift on Linux (where the support isn't nearly as strong, and a lot of the fancy new things coming out won't be available) or OCaml (from googling right now, a debate on reddit about "which stdlib should I use as a beginner" is on the first page of results when I search "ocaml std" or "ocaml stdlib").
One issue is that with GC, you lose prompt finalization of resources. A lot of code is written with this assumption in mind (e.g., file buffers are flushed if the last reference to the file is dropped—which is arguable incorrect due to the lack of error checking). And the borrow checker is the only thing that keeps everything from being mutable in place in Rust today. Having GC would open the possibility for alternatives to the borrow checker without compromising memory safety, but even Pony-style reference capabilities probably won't lead to a language where abstractions compose much more easily than in Rust today.
Maybe a language with a similar syntax, traits, monomorphization, and macros would still be interesting to many people? Would people prefer traits and macros over ad-hoc polymorphism (in the style of C++, which could subsume the macro use cases, too)?
I don't think constructors are the challenging part. It's about lexically scoped destruction. Certainly there are languages that have that and permit garbage collection, however those constructed values are necessarily second-class citizens and behave somewhat differently than ordinary values. There's probably some reasonable middle-ground, like constructors returning an owned reference that explicitly can be turned into an unowned reference, thus opting out of deterministic destruction.
> but I still think that there's a space for a higher-level language with most of what people like from Rust that has a (tracing) garbage collector and is slightly more relaxed with trying to design a way around every marginal heap allocation
I dream about a Rust subset that's exactly that. What would be even better is if you could just use Rust packages directly with it. Since these libraries already do compile, correctness has been verified.
A web framework doesn't need GC, it just needs some ability to express the idea that per-request code should get its own allocator, with knowledge of said allocator propagating down through function calls.
Jai solves this by having a "context", which includes an "allocator" member by default, whose default value is a standard heap allocator. You can override this allocator member to point to your own allocator, so it's easy and straightforward to have the main server procedure allocate a pool of memory, create a new context with a new allocator that uses this pool of memory, then "push" this context for the duration of the request resolution, then free (or mark for reuse) the memory pool afterward.
I gladly take the whole rust "package" because overall it's just so good, at least for opensource / hobby stuff. I wish there was an equivalent but with GC, to use for work.
> How did a language that's supposed to be so hard get popular to the point where people view its fans as pushing it aggressively?
I think Rust is especially popular with a demographic that was not previously exposed to lower level programming. Meaning younger programmers (because modern languages are higher level) and web centric programmers (because we're in a boom of web development).
This demographic had a hard time entering systems programming, because while fascinating, its exposure is lower (less jobs, less projects), and entry cost (learning C, or C++<11) is harder.
Rust made systems programming more accessible, and systems programming, just as anything related to how things work under the hood, is fascinating.
Now Rust is hard, as you noted, but not hard in the same sense than C is hard.
C is hard because low level stuff bites you immediately. You can't quite easily just use a random library in C if you don't understand your build system, linkage, etc. If you mess up in C, the compiler will not tell you either, you will have to debug your way out of it.
Rust is different, in the sense that its difficulty is limited to the compiler saying "nope". If you can get the compiler to say "yep", then you're 99.9% of the time safe. Now getting that compiler to say "yep" may take time, indeed, but all in all you most often can just get away with sprinkling unwraps, clones and Arcs all over the place until it works.
In that sense, I think Rusts popularity essentially lies in the fact that it is a way to do low level stuff with a barrier of entry limited to being stubborn in learning it.
Having learnt C in high school, and doing Z80 Assembly prior as a 12 year old kid, only with a bunch of books from the local library, it is kind of interesting to read about fear and hard regarding C.
Yes it does corrupt memory, there are some crashes, I usually bash C, nonetheless it seems we have too much "safety playground" regarding learning processes nowadays.
> How did a language that's supposed to be so hard get popular to the point where people view its fans as pushing it aggressively?
Popular languages don't really have evangelism or fans pushing it aggressively. Those are traits of smaller languages that don't interop well with other ecosystems so they need a lot of evangelism to build out the library ecosystem.
> there's a space for a higher-level language with most of what people like from Rust that has a (tracing) garbage collector
What non-memory management related things is it people like from Rust that is missing from, say, Java or Kotlin? Because those have great web frameworks that address all the features requested in the article and a whole lot more, there's good first class support for all major platforms, lots of documentation etc. These languages are also famously developer friendly with good error messages.
> Those are traits of smaller languages that don't interop well with other ecosystems so they need a lot of evangelism to build out the library ecosystem
> What non-memory management related things is it people like from Rust that is missing from, say, Java or Kotlin?
I'd argue that Rust has better interop with C, C++, JavaScript, Python, Ruby, and probably almost every other non-JVM language than Java and Kotlin. I'm not sure why you think that getting people to write more libraries is the goal of evangelization; if anything, I think Rust is somewhat notorious for people writing lots of libraries but comparatively fewer full applications.
Independent of interop (which I'm not really sure is as important to understanding why languages are or aren't popular as you seem to imply it is), I don't think the tooling in Java is nearly as beginner friendly as Rust. It's not just about the code itself; handling dependencies and building an application that you can run outside of an IDE are not nearly as straightforward in Java as plenty of other languages nowadays.
My point isn't that Java is bad or that doing things in it is hard in the absolute sense, but that "it's possible to do this in language X" is not the same as "it would be easy for a beginner to figure out how to do this in language X". I think there's an inherent lossiness in trying to distill what people like in a programming language into a bullet-pointed list of features, and it's an easy trap to compare those lists and conclude that one language doesn't have anything novel to offer based on that rather than the entire experience of working in a language.
Does Rust really have better interop? At minimum you're going to have to think about the gap between manual lifetimes and GCd allocations, bindings generation, ensuring the target language runtime is installed and so on.
You can call into JS, Python, Ruby and other such languages from Java like this:
It's very easy and requires no build-time bindings generation or Python/JS/Ruby runtimes to be installed. You can add Pip dependencies via the Java build system you use, as if they are regular libraries. It will also JIT compile the different languages together as one so the boundaries are optimized, you get transparent exceptions, callbacks work transparently as the whole heap is GCd as one, you can using a debugger in a unified way across languages and so on.
But this is sort of beside the point. Java once had lots of evangelism, partly to help build out the library ecosystem, but that was done years ago and now there are lots of libraries to meet most needs. So as a consequence you don't hear about it as much. This thread is a case in point. Lots of people suggesting rarely used languages like O'Caml or Zig, nearly nobody suggesting more obvious candidates that are used for this task, every day by nearly every big company in the world.
> I'm not sure why you think that getting people to write more libraries is the goal of evangelization; if anything, I think Rust is somewhat notorious for people writing lots of libraries but comparatively fewer full applications.
Wouldn't that be expected then? Rust has had lots of evangelism which has successfully yielded lots of libraries?
> handling dependencies and building an application that you can run outside of an IDE are not nearly as straightforward in Java as plenty of other languages nowadays.
I think this may be based on an outdated idea of how things work nowadays. I have my beefs with Java build tools but if you just want to build and distribute a web app it's easy. Using the stack I'm most familiar with:
1. Starting from a blank computer, install IntelliJ or other IDE of your choice.
2. Go to https://micronaut.io/launch and use the little wizard to pick whatever languages and features you want to start with.
3. Download the generated project, open it in your IDE. All the dependencies are now downloaded automatically including the build system and the Java runtime itself. Likewise if you picked features that use JavaScript.
4. Tweak it, run it. To ship it you have several options, but an easy approach is to add this to your build.gradle file (if you're using Gradle):
and then invoke the dockerPush build target, either from the CLI (./gradlew dockerPush) or the IDE. You can also compile it to a standalone Linux executable with another build target. That's all there is to it. I don't think Rust improves on this situation. Note that the above instructions work on any computer in the same way, including Windows, with no additional work required.
You're behind the times. Write a web app using a framework like Micronaut, Spring Native or Quarkus and you'll get a native Linux EXE out of the build system that starts faster than a C program would (due to pre-initialization).
Not that installing Java is all that hard. apt-get install openjdk is sufficient.
Last I checked there was a significant disadvantage to using rather basic Java JIT code in a cloud environment: slow startup time and poor initial performance in terms of requests per second & latency meant scaling on demand didn't work very well. I suggested we move to GraalVM and AOT compilation on that project but we just ended up over-provisioning by a significant factor to smooth things out.
The problem is friction. To run a rust app you can just run it. To run a java app you need to install java first. This is no problem for backends running on servers, but client apps (like Minecraft) have to include their own JVMs to reach a wider audience, and this solution still introduces a bunch of complexity.
> it is a matter to actually care to learn about their existence
That's kind of the whole point I was trying to make above; if one language makes something super easy to do without having to look for instructions compared, that makes a difference in terms of how people will decide whether to learn it. Individually, lots of small quality of life things add up and can make a language that otherwise would be unapproachable way easier to get started with than languages that don't prioritize that sort of thing.
If someone has two choices that can provide the same output, and one of them makes it more effort to figure out how to do, then people will do the other one more often. There's no inherent virtue is spending effort to do something equivalent. It's not clear to me why you seem to think that pointing this out deserves a sarcastic response.
Yeah, sorry. I was aware of that but was being loose with words. I do think that part of the appeal is rust feels more bare metal and direct to people even if they're using heavy abstractions as compared to Java/kotlin or C# programming.
Scala 3? It has the vast Java ecosystem available and state of the art GCs (plural), with either a focus on throughput or low-latency. Also, it can exclude the null value from the type system, marking it explicitly with a union type.
I think all NVM langs claim interoperability with Java ecosystem. The situation on the ground is never as nice as sold in my XP.
Scala is a great example where I've seen the "best" option being rewrapped libs with scala calls and types rather than a native solution and the dev XP just isn't as good overall.
You can hardly get higher quality code than what is generally available in Java, especially with their stability. Wrapping it to use the language conventions seems like a pretty solid choice to me.
The dev xp, I sorta agree on, but it has improved a lot.
Strongly agree, yet debates about improving the ergonomics of the language, for which there clearly "is a market", seem to be hindered by those zealous activists. A minority, I'm certain, but vocal nonetheless.
It really can be small stuff too, like hiding that nested generic "GC adjacent" type salad to be accessible only if you need it, via a type alias. Yes, I can define that myself, but the point is that a lot of people need it often, given its widespread use.l, so why not provide one?
I'm sure there's reasons not to do the above example, but that's not the point. It feels like Rust is at 95% of being amazing, and that the remaining 5% is attainable if we want to.
I used to think that it was more likely that Rust would "expand upward" to provide the higher level syntax that people want in a language like I describe above, but it does seem like the language development has vastly slowed down in terms of big new features. I don't necessarily think this is a bad thing; plenty of people didn't like how much churn there was in the first several years after Rust 1.0 came out. I personally didn't mind since I never ran into any significant breakage in what I worked on, but I definitely noticed a change in how open companies seemed to be to use Rust in any capacity coinciding with Rust's releases growing smaller on average; I think "frequency of major language features" is often used as a proxy for "language maturity".
At this point, I think a new language is more likely to provide this niche than Rust, and I also don't think that has to be a bad thing. Having Rust scoped more to lower-level programming where you're more worried about things like minimizing heap usage and avoiding copying strings or whatever rather than trying to be all things to all users might end up with a better experience in the long run.
> that are nothing even remotely close to systems programming
This is unnecessary gatekeeping. It also shows your lack of perspective. Or, rather, your lack of imagining other perspectives, probably.
Sure, rust is primarily a language aimed at systems programming. But it also is so much more (and also a cult).
* Its type system is excellent. Especially the lack of a "null". Even if, like me, you're fine with a GC, the type system alone is worth dealing with this insistent borrow-checker.
* Its multithreading is stellar. The borrow checker helps a lot in making it such.
* Its mutable/immutable model is highly practical. It's what makes the threading stellar and the type system more useful than in any other language I worked with.
* Its "oop" model is uncomfortable at first (coming from Ruby and Java) but forcing the "composition over inheritance" by not having inheritance is probably the best thing that can happen to "OOP". Every solution where I used inheritance, I shouldn't have.
* Its culture of "making the good way the easy way", being opinionated, and a community that adheres to this, is worth dealing with a thousand borrow-checker WTFs. cargo fmt, clippy, etc.
* Its build system that generates binaries that can just be "plopped" onto a server, "chmod +x" -ed, and ran is unprecedented.
I come from Ruby, Java, Javascript (typescript). I do a lot of Python, maintain some go services, have decades of PHP under the belt and occasionally dabble in some C and even C++. I can find my way around in a C# codebase and Objective-C.
All have their strengths and weaknesses. Their place and use-cases.
But rust, for me, is the only "ecosystem" that ticks all checkboxes in nearly all situations. It has downsides, and I consider the borrow-checker to be one of them in a lot of my use-cases, but it's something I'm willing to deal with gladly, because rust's other benefits.
a few months ago there was an article linked here on HN (iirc about rust game dev) that argued that while rust is great, it's virtue of being mostly correct every time can also be a weakness.
the argument was that in early dev and prototyping phases you don't want to write good, clean, correct code but move fast and break things while not caring about edge cases - and this, the author argued - is relatively hard in rust.
I partially agree. It's not so hard to write software that keeps the borrow checker happy in early stages. But it does restrict the freedom to make terrible decisions a bit. Sometimes in that stage terrible decisions are OK.
But I do like that even in this stage, one is forced to at least make the decision to have terrible things, explicit. Like with 'unwrap()' and 'expect()' littering the code in PoCs and exploratory projects.
For me, a bigger problem in this stage is that I lack the information to make decisions on types. I have this same problem in TS and Java. It's guaranteed that I'll shape types in ways that will prove difficult, or slow me down a lot next week. I'll be spending time refactoring types when I should move on to the next feature.
I guess, but that's just my experience, that statically typed languages are just not well suited for early stage software. When we don't know the shape of the data we'll be pushing around, nor know anything about the shape of the layers, ports, modules and so on. Which is why I'll grab ruby for these kind of quick explorations often. And once the shapes emerge, rewrite it in rust :)
I agree with you on the borrow checker... Part if me wants a simplified(distilled?) Rust ... All of the good stuff, but remove the bad... Not sure how that looks but it is something I know I want
A lot (all?) of the points I make aren't unique to rust, or even invented in rust. Many have even better implementations in other languages. Go also invented the "fmt", with one opinionated code style "enforced" by default - bikeshedding be gone!
My point was that it's the combination of all of these points. AFAIK, go ticks many of these boxes too. But for me golang falls short with mutability, and with the type system (though that one's catching up really fast). It's the "package-deal" that I like about rust.
I much prefer rust to go for many reasons, but IME go gets this part much better. Darwin / Linux cross compilation, armv7, FreeBSD, oh sorry you don't have a linker for that toolchain, wait where are those OpenSSL headers... lots of cross-compilation targets I've done in minutes with go that scp and run right away that end up being days / weeks of adventures to cross compile in rust, in spite of me knowing rust much better than go at this point.
I have had the luxury to work in projects that don't have to target many platforms, but rather "one": a server. Which then is often a simple linux variant so setting up a CI or even the local build to target that "one" is relatively simple.
But wasn't Go a lot more limited in the amount of targets it can build for than rust?
Yes and no -- obviously I can build for no_std targets like esp32 and atmega128p in rust but not go (haven't tried tinygo), but the proportion of targets that successfully built and ran IRL has been higher for me with go. On rust, the dynamic linking of libc (by default) and failure to include a linker with the toolchain have repeatedly been stumbling blocks, go "just works."
I didn't mean syntax or core lib to be similar, I just generally meant that both languages impose restrictions on themselves which might seem sensible at first.
Java isn't that restrictive. Rust's type system is much more restrictive and customizable.
That said, a good way to think about programs is a series of restrictions, i.e. invariants. Truth be told, only Ada Spark so far really embraced invariants.
I think RC and clone are the way people begin to use Rust. While lots of criticism are against this usage for not idiomatic, it should be acceptable. Coming from Python, nodejs or Ruby, even RC and clone or stack based variables is still a magnitude faster than those languages. When it's about absolute control for performance you can drop down a notch to the borrow checker behavior.
That's an interesting perspective I'd not considered before. Maybe there are different "registers" of Rust, in the same sense that linguists talk about registers in human languages, where you use your language differently for different purposes.
And thus, maybe if you're writing something that doesn't need to be screamingly fast absolutely all the time there's a register of Rust where putting lots of things in Rc<Box<T>> is completely acceptable, in much the same way that you might use a lot of impolite words around your friends but you don't in front of your employer.
Having written some Rust and a lot of Ruby, I find Kotlin to be a really nice "typed Ruby". Just like Ruby, Kotlin is an OO language in the core that is really friendly to FP. It's terse (not as terse as Ruby, as there are types to specify); but MUCH terser that Java.
> I think a lot of what people actually like about Rust, to be honest, is that it's essentially an ML language masquerading as a C-like, with a stellar packaging and tooling story.
F#is not C like and it's tooling and packaging is not as good as rust. Last time I checked it had multiple packaging solutions like paket and nuget. The tooling on vscode can be buggy
Yes F# has come along for the ride with modern .NET and it's as cross-platform as C# is. However, a lot of the really shiny .NET stuff is tooled up mostly for C# users, so it can be a challenge if you wanted to do something like a .NET MAUI (cross-platform GUI library) application in F# because the tooling and the content out there to teach you about it assumes C#.
F# can usually handle C# things - they put a lot of work into ensuring interop with new C# features - but the languages are from different paradigms so it is sometimes a bit awkward despite F#'s comprehensive OO support.
Personally I struggle a bit with F# because it doesn't have typeclasses, and a language that looks that much like Haskell but doesn't have typeclasses just feels weird to me.
Although it might get them... C# are looking at adding a traits-type feature (they don't seem to know what to call it yet, but the design's been kicking around the language team for ages now and keeps getting discussed), so F# could presumably piggyback on that if they wanted.
> C# are looking at adding a traits-type feature (they don't seem to know what to call it yet, but the design's been kicking around the language team for ages now and keeps getting discussed)
I'm in a startup using .NET. We deploy to a variety of targets including AWS t4g (Arm64) instances in AWS as well as x86/64 targets in GCP. All devs are on M1 Macs. Our build pipeline is GitHub Actions Linux runners. Our DB is either AWS RDS Postgres or GCP Cloud SQL Postgres with a mix of EF Core as ORM and Dapper (for more complex read queries).
C# has, over the years, converged with TypeScript so they are very similar[0] (though no Duck typing in C#). Good mix of OOP and FP paradigms borrowed from F#. F# interoperates with C# so it can tap into the larger C# ecosystem.
It's a good platform; very productive. CLI has a functional hot reload (much more limited than Node on JS as the granularity of module replacement isn't quite as good).
Don’t know if you intended this joke, but some time before Rust 1.0, @ was the sigil for garbage collection types (@T, like &T these days). Which I think was just reference counting, without even a cycle collector, because was shown to be undesirable before it could be improved.
I agree the type system is the best feature of Rust but neither Ruby or Elixir have the level of type safety and type expressiveness of Rust.
I'd recommend Haskell as an alternative, but Rust "fixes" plenty of long term Haskell annoyances (especially around laziness by default, concurrency, unsafe std).
Being able to use Arc<Mutex<T>>, Rc<RefCell<T>> and other smart pointers gives you granularity and control over what happens to your memory. I think it's a nice feature to have to mentally reason about your memory usage (incidentally a weak point in Haskell); even if it were on-par with a GC implementation-wise, why use a GC over this?
I like to have control over my code (and I'm probably one of the few who think monad transformers in haskell were a good feature - despite their clunkiness) and I'd pick explicit code over "magic garbage collection in the background" any day. This is not to say I like verbosity for verbosity's sake (eg. think React Redux in JS vs the implementation of the same idea in Elm) but in some cases I think it's justified and it brings extra value.
> Rust is great, but - heretic idea - not literally everything needs to be in Rust. Go try Ruby on Rails for a while! Or - if Rust has whetted your appetite for more functional styles - Phoenix on Elixir! Yes, it's not quite so blazing fast, but - let's be honest here - you're not going to be getting billions of requests per second on your hobby website where you write about taking apart Amigas. It's OK! She'll be right.
Who changes their minds about what to do for fun because someone on HN thought it was unnecessary? Doing what some random person wants instead because they want to be “heretical” (because it’s a religion right) sounds like the opposite of fun to me.
But I’ll see you on the next thread about making a Rube Goldberg web server in C++ templates. Or some such very necessary and “approved for prod by HN” thing.
> - Phoenix on Elixir! Yes, it's not quite so blazing fast
As someone running a fairly cpu heavy SAAS application for users who literally dog pile our whatsapp support forums if it goes down for even a second, Phoenix is pretty damn fast in production. I won't claim its as fast as rust but it will run circles around ruby or python and for IO bound tasks, competes perfectly fine with go. Its never been a bottleneck (database is another story)
If Rust had no borrowing at all, just Rc<> everywhere I'd lose maybe 5% interest in it, maybe less. Value orientation and Traits system, close to bare metal speed and stellar stdlib are what's most interesting for me.
I would say it shines when you have systems constraints, for example embedded & robotics work well with Rust. You cannot have a GC (either you don't have a heap or you cannot tolerate a GC pause resp.) but you still have the benefits of a good functional programming language to write your algorithms in.
The benefits are less obvious if you have less of those constraints: go is way way simpler to write large codebases for cloud applications in and still provide an excellent concurrency support. Python is way better for experimenting.
After reading endless insufferable comments on HN a la “this should have been written in Rust” I realized that there is a very strong possibility that the people making those comments do not know another language. We saw this with JavaScript a decade ago. Before that it was Ruby.
You gave a long list of benefits of Rust - which should have answered your own question - and then suggested people use an ecosystem with almost none of those benefits.
This is definetly something the article should have drilled down on. Why Rust? I'm sure everyone's tired of hearing why rust is an excellent alternative to c/c++ for new projects, but as an alternative against Python it gets muddier. Rust has a clear advantage in performance and memory footprint and a much better multithreading story, but those are things that aren't high priorities for 95% of web development.
That basically leaves you with Rust's type system. Rust's type system is pretty great, and if we pretend we can't hear the Haskell developers it's one of the best type systems out there. That might seem to get in the way of quick prototyping, but on the other hand it would mesh really well with a framework like Django. One of the great things of Django was that you define your data schema, and Django takes care of both the database and a passable admin area. I'm sure you could greatly expand on that principle, with data types driving a lot of behavior and conveniences that the framework just handles for you.
Maybe a bit like .NET, but without the enterprisy coat of paint and without putting dependency injection everywhere.
The answer for why folks are so inclined towards doing high-level tasks in Rust... is the type system. Its sensibilities are in a sweet spot that makes it very easy to pull off huge refactors. It was also a lot of people's first introduction to algebraic data types being used in nearly all error handling (its usage of `Result<T, E> where E implements Error` and lack of nulls or exceptions). It makes a lot of progress towards the goal of "make invalid states unrepresentable", which could be really useful for web apps.
Do they really have better economics? (EDIT: ergonomics!)
Last time I looked into OCaml, I struggled to find a way to interact with the database in a type-safe way, I never figured out which standard library I was meant to install, I was being encouraged to use 2-3 different project management tools (Dune + Esy + OPAM), and I gave up on writing tests. But at least there's a garbage collector!
I realise these are all problems that I'll wrap my head around over time, and eventually they'll seem completely trivial to me, but the introductory documentation on getting started as a professional (and not as a first-year student doing a French-language compsci degree, which is what most of the documentation assumes), is pretty dire.
Meanwhile, much as I'm sure I overuse `.clone()` and `[A]Rc<_>`, the ownership model of Rust is deeply useful. It's something I often find myself missing in Javascript - not necessarily because I want to produce the most performant code, but because it's useful to understand the lifetimes of the objects I'm keeping around. Am I accidentally storing a reference to something in a closure that I forgot about? When this object gets deleted, have I checked that it's the last possible reference to this object? Etc.
Like, I don't think everyone needs to learn Rust. It's a great language, but there's lots of other great languages out there, depending on your personal and business contexts. But I think this idea that Rust can and should only be a low-level language feels absurd to me. It is a fairly ergonomic language with a fantastic ecosystem, a powerful type system, and an ownership model that will be useful even if you do try and opt partly out of it with GC-like wrapper types.
Thanks for pointing the typo out! I've fixed the comment.
In fairness, I think a lot of this comes down to familiarity. I'm fairly familiar with `.clone()` and Arcs at this point, so they don't really change much in terms of ergonomics. Usually their usage is fairly obvious, and quite often my editor literally does magically type the `.clone()` calls through LSP fix commands. It's the same as, say, OCaml's insistence that recursion is better for complex loops than, say, `while` — it's not necessarily wrong, but if you're unfamiliar with the idea, it's going to feel weird.
More important to me is the ergonomics of the broader ecosystem, and that's something that Rust has done well, that other languages just don't seem to be interested in at all. Things like integrating testing into the standard workflow; working hard on getting the stdlib in good condition; having an excellent ecosystem of well-documented, usable libraries; or designing error messages and lints with a focus on getting people to understand how the language works and not just what they've done wrong this time. I've really missed that stuff whenever I've tried MLs. You mention, for example, REPLs, but a unit test is basically a saved REPL session that you can repeat every time you make a change.
I'm not trying to convince anyone that Rust is the best language in the world or something. I really like it, but I find it helpful to think in terms of object ownership even in non-Rust languages, and I can understand why for other people that sort of approach is unhelpful. But I would love to see other languages embrace its ergonomics more, or new languages created with that as their focus.
A unit test has nothing to do with a REPL, a proper REPL provides something similar to jupiter notebooks in feel, alongside debugging and hot code reload experience.
Maybe we have different understandings of REPLs. For me, a REPL is a tool that I can use to try out some portion of my code, see how it responds to various inputs, see how it handles certain cases, and explore the internals of it via debugging tools.
But... that's what I do in a unit test anyway. A unit test is essentially a REPL session that I've frozen in time, can replay whenever I want, can debug, can trigger a fresh run whenever changes occur (which isn't quite hot reloading, but often a darn sight more useful), and can keep track of and share with my team. Which means I'm not just able to explore things on my own, but I can see the explorations that other people have made with their code.
Typing in modern days is effectively moving the task of debugging to compile/ide annotations process instead of testing for correctness.
Albeit it makes the process easier compared to a really shittly written code without strict typing, but against good codebases, it takes the same amount of time.
If you think about correctness of a program, (i.e for any combination of given input , it changes a state in a determinstic way, including no state change for invalid input).
Strict typing is one way to accomplish this. The cpu does not give a shit about types. It cares about memory registers and locations. The unique code built into the compliers/transpilers is the thing that validates the correctness of the program in this case.
You can move that code into the testing suite without relying on the complier, and just do testing. Generally, given competent programming skills, this takes about the same amount of time as designing a well structured program - your tests are pretty much your design document for the thing itself.
This is a very anti-pragmatic way of looking at things in my opinion. The program is not a snapshot that exists in a vacuum. Most programs are going to grow over time and have things added and removed in various places by many people. They're going to have many interfaces and operations.
I think you're arguing that tests and types can both be used to check a particular case for correctness. Sure, this is true. However "moving type checking code into the test suite" means nothing—that would just be type checking.
When you make a code change, there's a difference in the kinds of feedback you get from your tests and your types. Tests usually cover business logic or stories—things that you want or don't want. Types ideally cover everything. They check every operation applied to a given piece of data. Of course types are rarely precise enough that they can catch every logic bug (e.g. strings with semantics not encoded in types, like email addresses).
This is just scratching the surface. You might just have to try out both to get a better sense of how they feel to work with.
So at one of my older jobs, we worked primarily with C code that ran on a mini linux box inside a plane, and interfaces with a sensor pacakge. We wanted to make sure that the software was 100% correct cause any errors would mean an aborted flight test
We basically ended up creating a tool+language spec that would let us define the mapping of input to output sequences. We wrote it in such a way where we sat with scientists and pretty much mapped all the possible cases that they could think of for valid inputs and what the code should produce.
Then this tool would basically write automated tests for us, in such a way as to not only test correct behavior, but also do combinations of inputs out of order, fuzz testing, and so on. We ended up making it also check memory state, to ensure that there was no memory leaks, and analyze the memory space for required data or data that should not be there.
In the end, whenever someone was developing anything for this software, they would basically just run the tests, and it would be very good at catching possible errors, mostly on the negative side (i.e for a fuzzed input, it would result in an output that should be an error).
We could have done the same thing with a typed language, but it would have to be very strict typing to the point of something like CoQ, and it would have taken us probably the same amount of time to write that.
Hey, that's awesome. Seems like a great case for verifying things that way! I'm thinking of different cases I think, where you've got something like a distributed system or a web application and it's just harder to fuzz. But I agree, that seems a lot more practical than formally verifying it when that's the kind of testing you need.
Types [1] can only reason about categories of values, not about values. Tests and types do have an overlap, but the best option is both. Especially when combined with fuzzing, types can exclude large number of cases, making it even more efficient at covering a huge range of code paths.
[1] yeah, there are type systems like lean, coq that can do both, but the proving process is just currently not realistic for everyday applications
1. refactoring are in my experience still much faster (and reliable doable) with rust compared to e.g. Js/Python even in presence of a lot of tests. This is a bit less of an point with Java/TS/C# etc. through I had some very bad (and also some good) experiences with refactoring in TS. And to be clear I don't just mean pure refactoring but any larger changes affecting many places in code which might be needed to idk. impl. some feature.
2. especially with Js,Py and similar there are way to many edge cases you can have to test for all of them. Sure most times this mainly matters when writing libraries but on larger projects does apply too. Stupid stuff like you expecting a `list[int]` and someone (externally i.e. outside of your tests) passes a `dict[int, int]` and that happens to work as you current impl. is only linearly iterating it as if it's a `Iterable[int]` but then you change the impl to require a `Sequence[int]` as you access it by index in some corner case and now you customer has really strange subtle bugs. Can't be caught by your tests as the problem is the customer but still breaks the customer which is always bad and can't happen with rust. Sure also won't happen if everyone uses type annotations and mypy correctly and strictly. Through you can't rely on your customer using mypy, but you can rely on your customer running compiler checks (as it's the only way to build the code). Also while mypy is much much much better then pylance it is still prone to issues as both `cast` and `ignore[..]` are things you sometimes need but which easily can hide bugs if the code changes (cast doesn't pin the "from" type and ignore is scoped by place not by what is wrong)
People who say copilot is useless.... I can only imagine they're in a dynamically typed language. Copilot + Rust makes boilerplate go fast. Strong typing is force multiplier for code gen.
I suspect that’s true. I never blindingly copy LLM generated code (that would be recklessly stupid), but I often only quick skim rust code generated this way, just to make sure the general task it is solving is what I asked for. If there is an unhandled edge case or or memory handling bug, rust will catch it.
It's also easier to implement a generate_code -> check_for_errors -> give_error_to_llm -> fix_code loop, because the errors that rust throws at you are most of the time really well thought out, and as succint as usefully possible. Comparing it with python, where you have to write custom parsing to trim it down and even then it's hit and miss on where the actual error lies, it's not even funny.
Rust does not skirt around the fundamentals. You can still handle errors however you want, you can still blast side effects all over the place, and you still have to uphold an arbitrary set of invariants specific to the task at hand. But the ecosystem as a whole is filled with things being done the right way because the language and its linters have always been quite helpful.
In any program there are errors you can handle and errors you can't, errors whose vary existence suggests something has gone horribly wrong. What else should you do in that situation but panic?
I see unwrap used all of the time on things that could be recoverable if people bothered to write the control flow. “Meh, let the program crash” is easier because unwrap is much less verbose than the match unpacking or carrying results to callers.
Rust has exceptions, they are just named Result and people just as frequently decide not to handle error results as not catch exceptions in my experience.
Typed exceptions are just as good as what rust offers IMO.
Interesting, great example. This kind of compile time safety can't be achieved without borrow checker, I guess? I'm now thinking hard if there's some type magic similar to the exhaustive checks for Typescript discriminated unions ("kind satisfies never" checks in switch statements).
I've been trying to come up with a similar pattern in TS many times but I think you cannot do this due to the lack of moves (bindings do alias, pass by reference).
But TS has so many dark magical patterns that I'm still hoping to be proven wrong.
Shared mutable state is a problem even in single threaded code (for example, modifying a collection you're iterating over)
> And does Rust have type unions and intersections, interfaces, and mapped and conditional types?
You can typically accomplish the same thing with enums/proc macros/traits of course—with the additional benefit that the type system is designed to be sound. Soundness is an explicit non-goal of TypeScript[1], so once you start layering on those kinds of overly-clever types, you soon reach a point where you're just lulling yourself into a false sense of security.
JS has concurrency (but not parallelism) despite being single-threaded, though.
If you ever put an await anywhere in your code, an arbitrary amount of random stuff might run between the time you await and the time the awaiting finishes.
Same applies to older mechanisms like callbacks and promises.
Race conditions are more rare there because as long as you aren't doing any IO, there is indeed no concurrency, so you can't e.g. get two threads trying to increment a single variable at the same time. They can still happen, though, especially if you accidentally do a partial change to an object, put it in an illegal state, and do IO before you finish that change.
> The vast majority of errors caused by shared mutable state are related to concurrency.
Concurrency, like async-await, you mean?
> TypeScript's type system contains features that Rust's does not have
Sure, and likewise Rust's type system contains features TypeScript's does not have—for example, just try expressing anything close to traits with TS's type-erased generics. Since the feature sets aren't the same, I suppose it's a matter of opinion which type system is preferable. But I know which one is more helpful for me for sure (especially considering the aforementioned soundness issues).
idk. many years ago through stuff like service workers, having shared memory through TypedArrays and similar.
But for the discussion more relevant is that shared mutability constraints do not only matter with threading, they matter with any form of concurrency (like JS async/await/promises and before that callbacks). And even without that you still have other single threaded and single tasked concurrency with the classic being changing a collection while iterating over it. So even without classical forms multi threaded concurrency still very helpful.
> And does Rust have type unions and intersections, interfaces, and mapped and conditional types?
Rusts type system is mainly nominal typed while TS is mainly structural types so it's a bit hard to compare. Like if you nitpick then you could maybe argue that based on TS type system having "features rust types system doesn't have" it's more powerful (but you also could argue the other way around it depends on how you count them). But that would be misleading as it ignores that not only are they two fundamentally different approaches to typing it also ignores that some features are implemented through other means outside of the type system.
Practically having used both I can say that while TS has some things in the typing which are a bit cumbersome to do in rust when it comes to helping me having correct code in context of changes, especially larger changes, and especially libraries Rust still yields better results in my experience. Naturally assuming you don't abuse the TS in either case.
(and to technically answer the question, type unions == yes but different, intersection == no but also make little sense in rust, interfaces == yes but different, mapped types ~= depends on the aspect in some yes and better then TS in other no but implicitly through derives so worse then TS, conditional type ~= again handled through different features depending on usage either associated types or feature gates)
For what I hack on I often run into issues with the FFI performance between go/c# <-> c/c++. I’d rather not write C or C++ and Rust is one of the few languages that allows me to mess around with obscure libs at native performance and yet slap a web interface in front of it. cxx/bindgen is stellar in how fast they allow you to wrap libraries. These cases is where I would want like the simplest most opinionated web framework (like gin in Go).
Have you had real success with cxx? I've been trying to FFI a C++ lib (that I have limited control over) and it's been a real PITA. At this point I'm thinking of just making a pure-c interface for what I want on the C++ side and using C bindgen or just straight "extern C" because C++ FFI seems so painful.
FFI can be a source of performance issues in Go but not in C# (at least not to the same extent), unless you go out of your way to fight the happy path approach.
Sometimes you do have to rethink what you marshal vs what you just manage manually, but that’s what pointers are for (that can be turned into ref Ts for single values and into Span<T>s for slices/arrays/etc). The idea is that performance ceiling of FFI in .NET is as cheap as direct calls.
> but as an alternative against Python it gets muddier
For me, a clear advantage of rust (and also Go) over Python (or Ruby, or PHP) is not having to deal with runtimes.
With Python, the server needs all sorts of setup. Exactly the right version and configuration of the runtime. Pip. Or Pipenv. Or Pyenv. Or Conda. Or... and so on. Then it needs the libraries installed. Some of which must be built natively; so just packaging them in some CI is often not even possible. These native builds need lib-something-dev packages.
Then with an update of the underlying server, suddenly nothing works anymore.
Having a single binary that I can plop onto almost every linux box and which "just runs" regardless of the exact version of Ubuntu, cargo, rust-toolchain on the server/hosting machine is invaluable.
I'm so done with maintaining the fragile card-house that my Ruby-on-rails apps require, or that my python/flask services need, that my nodejs insists upon: with rust this is no longer needed.
And yes, docker/containerization is a solution to it. And yes, I know about the options to package up a python app with runtime included. But all that adds extra complexity. It merely makes it easier sometimes. Not simpler. And it inevitably makes troubleshooting, upgrading, etc even harder in some future.
Between Rust and Python there are a huge distance full of options with managed compiled languages, with AOT, JIT, or even both AOT and JIT as standard toolchain feature.
> and if we pretend we can't hear the Haskell developers it's one of the best type systems out there
Eh, Rust's type system isn't one of the best out there. It's lacking higher kinded types, etc. It's abilities in type level programming are frustratingly limited as well.
So it's advanced aside from from Haskell, OCaml, Idris, Scala, etc. Compare to OCaml's effect system for an advanced type system feature.
I 100% agree with you (I really miss HKTs), but I don't think the GP was using "best" to mean "most fully-featured".
And with that in mind, I do agree with the GP. Scala's type system, for example, is full of warts (well, Scala 2; I still haven't tried Scala 3). Rust's is cleaner and has fewer gotchas. I very rarely have to look up how to express something in Rust's type system, but I remember when I last did Scala, I often ran into weird type-system related errors that I just didn't understand and had to dig into to figure out. Some of that, sure, is likely due to Scala's type system having more features, but some of that is because it's just more complex. And I would usually rate something of lower complexity as better than something with higher complexity.
One of the major things about Scala 2 vs Scala 3 is the removal of many of the type system warts, in particular the type hierarchy now forms a lattice (if I'm getting my terminology right) rather than being rather adhoc in various places.
Lots of other small annoyances like the whole tuple situation have also been fixed.
EDIT: Plus: intersection types, sane macros/inlining, etc.
Unfortunately (for me), some of our projects still have to cross-compile to 2.x, but that's irrelevant for greenfield.
I'd give it a whirl -- it's a great improvement over Scala 2.x.
OCaml's effects are fairly new, and the Rust maintainers are also looking into effect systems. Who knows, we might also get HKTs and dependent types too in the future.
The author is clearly building things for the joy of it. If she gets the most joy from Rust, that's what she should use!
> See, if I want to make something for the web, I could use Django but I don't want that. I mean, Django is for building serious businesses, not for building silly non-commercial things!
Personally, I spent the first decade of my career switching between languages, believing that I should use the best tool for any given job. I spent the last ~five years doing mostly Rust, and I've learned that there's a level of mastery of a language you can never quite reach if you're always context-switching between them, especially a language as “deep” as Rust. This means I write things in Rust that Rust is not the best language for.
> If she gets the most joy from Rust, that's what she should use!
In the past I’d try to justify why I’d done something a certain way when another way would’ve been faster / better / cheaper, but I now realise that (at least for personal pursuits) an acceptable answer to “why?” is simply “because I wanted to”.
I feel like this is where I've personally landed with Rust. For many applications, it's at least good enough. It gets the job done. It looks and feels professional. Fit and finish are rarely a material concern. It rarely causes active problems (except where there isn't native coverage yet) and reduces or eliminated many more. And... well, I like it.
If I were putting together a web development team, would I recommend Rust? ...probably not. But that's because I'm putting together a team, not a playground. I'm paying people. I want to use common, well-supported, time-tested methods, unless steering away from that is truly needed to make the project successful. For web dev, that assuredly ain't Rust ("yet," some may add).
But for me? Just for me? I think it's a language I'll always enjoy. Within that line of thinking, I do feel there's room for better web dev tooling in Rust, though what's already there is probably enough to at least get started.
Let's just say different people have different opinions on this one. Personally, I find Go to be a big regression in language design given modern PLT research, and wouldn't use it unless forced (e.g. terraform providers). Other people have other opinions: a friend I respect a lot has great success in the Go community.
I'm telling you that because if, as a Go enjoyer, you're baffled by the writings of a Rust enjoyer, it's very likely the result of different perspectives rather than silliness. And if your conclusion is "just use go", you're probably the one being silly.
What kind of logic is this... The Rust language is quite rigorous, so web frameworks on it should also be equally laborious to work with? You have to roll your own authentication, you have to do your own routing, you have to do ad-hoc string manipulation instead of templates?...
The person likes writing in Rust, and would like to have a batteries-included web framework so they can tie together a web app quickly on the language they like to use... And I know they did not include https://rocket.rs/ in their 'existing ecosystem' section.
If you find the language rigorous, a web framework can't magically do away with that. It's genuinely illogical to believe so. There are plenty of web frameworks on Rust that are quite nice to use, but they are still Rust, with all its shortcomings in the same way Django is still Python with all its shortcomings.
What you're asking for is a DSL built on top of Rust for the purpose of creating web apps.
Show me where I asked for a framework that magically turns Rust into Ruby. The person has created a list of (high-level!) features that they need. None of them are 'no borrow checker'.
It'd be cool to have an out of the box "90% of what a website needs" toolkit that means writing your 10% custom code/secret-sauce in a modern code security obsessed language. Even if it is opinionated and "batteries included" in ways that make some things annoying.
I have built many projects that start with a WordPress install, to piggyback it's CMS, user management, and admin backend. I then inevitably end up making a choice between writing the project in php, or jumping through hoops to use the WP features (like auth and user accounts) in some other language that's more appropriate to the task at hand.
I mean, OP is working on such a "magical" web framework now. Time will tell how it turns out, and how usable and magical it ends up being. But at least the author isn't just whining; she's put her hands to the keyboard and is going to try to get it done.
> What you're asking for is a DSL built on top of Rust for the purpose of creating web apps.
I don't think that's necessary, personally, but if someone really wanted that, I'm sure they could come up with something that can be wrapped in a Rust macro invocation, that gets expanded to something smaller and faster (compiled-code-wise) than anything you can get in a Rails app.
For what it’s worth, for me, the time-to-first-attempt-to-run-it is faster in Python or Node than Rust (sometimes), but the time-to-first-working program is generally not, and by the time I have the Rust one working, it handles most of the corner cases with clear error messages. There are rarely unexpected cases not handled.
In other words, I find it faster to produce working stuff in Rust and much faster to produce quality stuff.
I don't as a rule web dev, so when I do I fall into the same category as the author: lowest effort to get something mostly right.
An explanation for "why bother try to have a low effort web server in Rust?" that I haven't seen mentioned: Once you're past the introductory phase of being familiar with Rust, if you don't need to pedantically handle every error case, it can be _very_ simple.
A low effort "doesn't have to be very flexible" web server would be terrific & easy to use in Rust.
Having said that, I'm not aware of the actual offerings available. Maybe there is one, other posts have suggestions.
Rust has benefits besides just memory safety and being efficient, it has great language design and a great toolchain. I chose (learning) rust over golang for quite simple projects with no performance requirements, out of sheer frustration with the toolchain/design of go, golang came off to me as "let's try to be special and make bizarre design decisions" which made it confusing to learn, not only that but I very quickly ran into pain points, whereas rust felt like everything just took the most logical straightforward path, and everything "just worked". It, to me, genuinely feels simpler, because things were what I expected. Kind of like apple simplifying their mouse to have no buttons and thinking it's very simple and easy, but then its just more complicated because it's so unusual, whereas everyone knows exactly how a normal mouse works. Just my view. I use typescript and needed a language to make a couple simple programs that could compile to a single executable, I'd love another option but don't want to use one that's not matured enough.
Strange - my experience was the opposite for Rust. The extreme plethora of String types, the way life time annotations made refactorings very difficult with very high cognitive overhead, no batteries included standard library, even error handling needing external support, string slicing panicking in Rust, async is a mess to debug - Go in contrast is a far more comfortable and consistent developer experience.
Basically the type system, most rust projects usually don’t come near “The advanced Reason there’s rust” and if they do need that there’re hardcore libraries for that, an ecosystem like that usually suffers from exhaustion cause no dev will want to maintain just a library and this is also the good apart of rust cause it lessens the barrier into the language as the ecosystem gets bigger
Go look at job boards. The competition for Go, Rust, Django or whatever is Java+Spring. That's pretty much the industry standard unless you're in a Microsoft-only shop.
It’s disingenuous to leave out C# and F# out of this, given how much closer they are to Rust in language features and how much more “close to the metal” capabilities they offer while also having opinionated web frameworks, better CLI tooling and package management and being generally very productive languages.
I specifically mentioned Microsoft and pointed out that it's mostly gonna be Spring unless in an MS shop. C# wasn't mentioned explicitly because I thought it was clear what was meant.
Then the statement is incorrect, unless you want to indicate that it’s region-specific.
Edit: I read other comments. Disregard my replies then, because this is likely intentional. Luckily, I had enough interactions with Java communities to know that many other people there are not biased.
I don't see how people can "love" writing rust either. I love a lot of things about Rust and its ecosystem, but the syntax day-to-day isn't one of those things.
I use Rust primarily due to the type system. I could use OCaml of course but its a tooling nightmare compared to cargo. The fact that Rust is fast by default is just a plus.
It could beat using C/C++ for using an embedded web server. I remember I tried that once and a lot of the work was using aho-corasick for working with paths, handling cookies and dealing with a bunch of nasty error handling all of which in theory would be easier in rust.
My problem wasn't so much dealing with memory management, but trying to put an upper bound on memory usage and failing nicely when that upper bound is met. I generally don't like working with garbage-collected languages, or having to use some niche application-specific language when I can just use a general-purpose language instead.
As a Linux user I’ve had to deal with these kind of people who wouldn’t use something new unless it was made the same of what they’re currently using, all my life, they just are not able to get it
> I think this part is perhaps the silliest part of a very silly article. If you really like to put in a minimal effort then why on earth would you use Rust?
“I like to play basketball but tbh I like to put in the minimal effort”
“Then why do you even play basketball? It’s a physical activity…”
The first thing takes precedence over the other.
> If you want efficiency, memory management and a compiled modern language just use Go. Then you won’t even need anything but the standard library for what you want to do. Or… use Django as you suggest?
Just do what someone else dictactes. The surefire way to self-expression and Fun Town.
> Yes, yes we use Rust in production because we thought it would be easier (well safer) to teach to interpreted language OOP developers than c/c++ but why on earth would you ever use it for the web unless you are a member of the cult?
You forgot to capitalize. The Cult. Since you apparently want to look silly.
There’s a difference between what you do in production (at a job presumably) compared to what someone does to be “silly”.
> Yes, yes we use Rust in production because we thought it would be easier (well safer) to teach to interpreted language OOP developers than c/c++ but why on earth would you ever use it for the web unless you are a member of the cult?
Rust is great, high level language that's super convenient for implementing arbitrary algorithms on arbitrary huge, complex data structures safely and quickly. Value semantics is absolutely unique and useful. The system of traits and standard library using traits like Ord or Hash means that it's enough for your type to implement one of those and suddenly it can be a key in a HashMap or BTreeMap and can be a part of even larger and more complex data structure. Adding a web to that easily could be super useful.
Seems like a good enough reason to use it to me, but perhaps I’m just another cult member.
> we use Rust in production because we thought it would be easier (well safer) to teach to interpreted language OOP developers than c/c++
I think rust is just safer period, regardless of your level of expertise or background. Or are you saying that every memory safety bug was written in by someone inexperienced?
Not to mention the concept of “sharing code.” See I may write garbage tier rust code that basically glues together a bunch of libraries, many of those libraries are written by programmers way better than me, and I can gain performance and safety from using their work. The performance difference between languages like Rust and JS is huge, even if I, tainted by my background in Java, write dogshit code.
> I think rust is just safer period, regardless of your level of expertise or background. Or are you saying that every memory safety bug was written in by someone inexperienced?
I think you're reading too much into that and creating conflict where there isn't any. GP just meant that they had a bunch of interpreted language OOP developers (probably Java or C# or something like that), and they wanted them to start writing code in an AOT-compiled language (yes, I know about Graal native image; not the point). And that teaching them Rust is probably going to result in safer code than if they were to teach them C or C++.
> GP just meant that they had a bunch of interpreted language OOP developers (probably Java or C# or something like that), and they wanted them to start writing code in an AOT-compiled language (yes, I know about Graal native image; not the point).
JIT vs. AOT is not the same as being an interpreted language. For most applications, running on top of the virtual machine is a good thing, I don't see JVM developers turning to different languages just to escape the JVM, outside of some niche projects.
Also, without claiming that experienced c/c++ developers never write memory safety bugs, I don't think it's at all controversial to say inexperienced c/c++ developers write a lot of them (and hopefully experienced ones write way fewer).
I was trying to out that wanting to take the easiest path was rather contradictory to working with Rust.
> I think rust is just safer period, regardless of your level of expertise or background.
Yes, I’m not sure how you think I was implying something different. We (specifically) adopted it because it was easier for our (specifically) developers who weren’t familiar with low level languages to work with compared to c/c++.
> many of those libraries are written by programmers way better than me
You shouldn’t sell yourself so short in my opinion.
From a technical point, you are absolutely correct. From a developer heavy business, it's a little more complicated.
If Rust had a good full-fledged web framework, it would enable more developers to justify why the business should use Rust. The culprit is that it would require a heavy education budget, but it would in turn enable the business to allow using Rust for other parts of the business which could benefit from Rust, e.g. middleware, small components, CLIs and systems programming in general.
Having a little bit of Python here, a little bit of Go there and a bit of Java elsewhere can become chaotic. There is a huge benefit for a small company to only have 1 programming language everyone agrees on using.
If your goal is to use just one language then why wouldn’t you pick JavaScript (likely Typescript), C# with Blazor, Go with templates or basically anything on the JVM? Rust is a bad general purpose language in my opinion, and its performance isn’t actually good enough compared to C# to really justify the added headaches. I say this as someone who really, really, doesn’t like C# by the way.
If your goal is easy web development, Django, Ruby on Rails and Laravel are frankly going be extremely hard to beat. I prefer Go with templates, but that’s still much worse than those options.
I feel like my Rust code takes 3x as long to write as my Python code, but the gpt results for rust are about 10x better, because the tooling is a backstop against hallucinations.
I really like the Rust tooling and I like exhaustive pattern matching. Python post-dev debugging time is probably 10x vs Rust. That's why I choose Rust.
> If you really like to put in a minimal effort then why on earth would you use Rust
Because it's a fun language and you really do get to avoid the borrow checker nowadays if you just use `Arc` and `Clone` all over the place. I'm the same as OP.
Also, I love the package ecosystem. I know it (rightfully) gets some of the flack that the JS ecosystem gets, but most of the time, I truly don't care. I enjoy C programming as well, but C not having a common packaging system / cargo equivalent has really hurt it a bit in my opinion.
I think this part is perhaps the silliest part of a very silly article. If you really like to put in a minimal effort then why on earth would you use Rust? If you want efficiency, memory management and a compiled modern language just use Go. Then you won’t even need anything but the standard library for what you want to do. Or… use Django as you suggest?
Yes, yes we use Rust in production because we thought it would be easier (well safer) to teach to interpreted language OOP developers than c/c++ but why on earth would you ever use it for the web unless you are a member of the cult?