Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Zero to Production in Rust (zero2prod.com)
258 points by belter on June 5, 2021 | hide | past | favorite | 193 comments


So I've just tinkered around a bit in Rust, and I'm not intimately familiar with the language. My experience has been pretty good, but I don't see how it's a good fit for the web domain. At least not the enterprisey, CRUD, business apps I'm used to building.

I'd be curious to hear from people who have been using Rust for their web backends, though. Beyond the classic selling points of speed and safety, what benefits have you found that apply to web development? Have you had any issues with the ecosystem or finding developers?


We are using Rust for backend web development and other things.

For us, the safety is the critical reason to choose Rust - particularly the thread-safety. Also the relatively small memory footprint compared to something like Java. Performance hasn't driven our decision at all - the number of requests per second is very low. It's correctness that matters.

We are a bit unusual because customers have locally deployed servers rather than servers managed by us, so bugs are harder to fix.

We haven't hired any developers specifically for their Rust experience, but have instead trained internally and now have a group of about 10 Rust developers working across a couple of projects. I would say that training like this has been relatively straightforward. One of our hires, a recent graduate, had some existing Rust experience with personal projects, and this was particularly beneficial in helping the team to bootstrap.

The ecosystem is surprisingly mature. Async is probably still shaking out somewhat, but that's moved on hugely in the last couple of years, and we haven't had any particular problems.

Overall the experience has been hugely positive.

The biggest barrier to adoption, in my opinion, is that people are scared of learning Rust because it has a reputation as being difficult. I don't think it's any harder to master than some other major languages such as C++ or Java - although perhaps you have to understand more at the beginning: ownership and borrowing are right in your face.


> I don't think it's any harder to master than some other major languages such as C++ or Java

Oh there is just no way it's harder to learn than C++. C++ has the problem that it's all of C (almost everything from C is still in there) plus all the stuff bolted on to achieve C-with-classes when OOP was the new hotness in the 1980s plus then several further evolutions to add major new features, not always in a very consistent way.

There is a sub-tribe within C++ that wants a simpler "subset of the superset". They believe C++ could be made into a healthy modern language which is practical to teach as a first language to students and still has excellent performance and hardware compatibility. But if you speak to members of that tribe they invariably feel there's just a few little tweaks to make to the superset first... and I just don't think their dream will ever actually come true.

Rust does have a lot of complicated stuff, but almost all of it secretly turns up if you wanted to be good at C++ too.

For example, borrowing versus ownership isn't explicit in C++ but it's necessary to understand what's actually going on so that you'll find Stroustrup has actually written proposals for C++ that formalise this exact notion, they just can't be checked for existing C++ as they are in Rust.


> There is a sub-tribe within C++ that wants a simpler "subset of the superset". They believe C++ could be made into a healthy modern language which is practical to teach as a first language to students and still has excellent performance and hardware compatibility.

Yes. There is a "c++" which is simple, consistent, and fairly easy to use, but it's buried in the cruft of decades.

The biggest complaint about Rust's "hardness" is ownership and move/borrow mechanics. Modern C++ has std::move, ownership, and lifetime considerations.

Add to that smart pointers, initialization, a bloatastic std lib, an even more bloatastic pseudo-std lib that you need if you have to interop with anything older than 14 (boost), umpteen different build systems, compilers, toolchains, and all that on top of almost-not-quite-C-superset, and you have a massive surface area.

On another HN thread, someone commented that developers took 3x longer to get to speed in a Rust codebase than C++. I say no way, Jose. I was committing PRs in Rust within a few months. I still don't feel comfortable in C++ of any serious complexity. That's with 2 years of C experience, 1 yr of intensive C++, and like, a few months of rust.


Having written C++ in one way or another over the last 2 decades I still get burned by that surface area.

Last week it was a combination of forgetting the exact specifics of RVO hitting the implicit copy constructor that was causing things to go sideways. The number of implicit behaviors are pretty wide and things like move semantics still feel pretty brittle.


Yeah this is exactly the kind of thing I mean. I worked at the company that makes CMake and I'd go to coworkers with questions like that...I forget exactly what I asked but it was something involving RVO and copy elision of a lambda/ anonymous function, and they had to ask around until we found a greybeard who knew the correct application of && and some other stuff. This wasn't even some heavy deep stuff, it was like a pubsub callback in ROS.

I had some really mission critical camera driver stuff I was working on and just never felt secure that there was a massive bug lurking, despite code review, Valgrind and testing. But on that same project, I had enough confidence to write a small daemon in Rust, with like...maybe 60h total experience in the language. Huge peace of mind knowing the code does what I expect it to do.


> Rust does have a lot of complicated stuff, but almost all of it secretly turns up if you wanted to be good at C++ too.

This is mostly true. As FP and Rust have shown us, if you can treat an input data set as immutable, while building up the result data, you have a much easier time. I bring those patterns into my C++, which speaks to your point.

I'd offer one exception though: mutability xor aliasability on a per-object basis is something I wouldn't take to my C++ code. It may be the core of Rust, and it's a neat tradeoff that enables some of its other benefits, but the indirect complexity cost is too high, IME.

> Oh there is just no way it's harder to learn than C++.

I think the jury's still out on this one.

C++ has complexity, but has the benefit of a gradual learning curve. You can start with C, slowly add `virtual`, then add templates, then add the STL.

Rust has just as much complexity, and forces it all on you at once. Because of that, it is harder to learn.

Some people say Rust's rules are intuitive. I have to disagree. These years of working with Rust and teaching Rust to others have made it clear to me: though the basic concepts are simple, the architectural implications and workarounds are not.

I'm not saying C++ or Rust is better. But C++ is slightly easier to learn, IMO.

I commonly hear "But it's hard to learn how to use C++ safely!" and I generally agree with that. ASan has made things much easier in that regard, but C++ will probably never catch up enough for some use cases.


> C++ has complexity, but has the benefit of a gradual learning curve. You can start with C, slowly add `virtual`, then add templates, then add the STL.

Having seen teams go Java -> C++ and other teams go C -> C++ I don't really think that's the case. The former leans on shared_ptr everywhere, the latter ends up hitting footguns with implicit behavior around move semantics, RAII(seen more than a few use after free here) and the like.

ASAN and other tools help, but assume they are run regularly and kept to a level of rigor I haven't always seen in codebases.


To be fair, people coming from other languages lean heavily on Rc/RefCell too, and sometimes (uh oh) unsafe blocks.

In both cases, one benefits from input from those experienced in the language.

(not saying c/c++ is better than rust, just commenting on the difficulty)


Yeah, but rightly so those are "escape hatches" because you can leak memory with Rc/shared_ptr.

With C++ unless you have someone experienced on a team there's a host of "unknown unknowns" that feel like the team is making progress but then having to pay the cost when it blows up and usually when schedule pressure is near the highest point. Same for the build systems, retrofitting LTO is not a fun experience.

Rust in contrast calls out many of those things upfront, I've found those guardrails prompt conversations in tradeoffs and conscious choices(to say use Rc/RefCell) you'd be making anyway in C++.


So it's okay if rust does shared ownership, but not okay for c++?

I'm not attacking rust, btw. We all know c/c++ isn't great. Theres plenty of aspects where rust is better, and plenty where c++ is better.

But we're just talking about difficulty, and in this context it's fair to say rust isn't necessarily better than c/c++.


Shared ownership is code smell to me regardless of the language, I think Rust just makes it a bit more high friction.

Language difficulty I'm having trouble seeing how C++ isn't harder there. You have decades of features, lots of gotchas that I could rattle off and a bunch of implicit behavior that you only learn about when it blows up at runtime(if your lucky). Heck, I've seen heap corruptions stay latent in codebases for 6+ months only to have a new field added that causes them to cascade into a failure that took 3 weeks to debug across 2 different teams. I've still seen modern compilers not catch basic use after free scenarios in code today.

I won't disagree that you can get code to compile quicker in C++ but if your goal is feature velocity you're better served by a high level language. If your goal is stability, performance and memory which is the domain of systems programming then I think C++ has a bunch of hidden failure modes that Rust frontloads in an elegant way.

There are projects where you'd pick C++ for portability on platforms LLVM doesn't support or momentum with existing codebases but if I had to pick between the two my personal bias is towards Rust for all the reasons above.


> Shared ownership is code smell to me regardless of the language

This is an unsubstantiated claim. If Rust makes something hard, that doesn't automatically make it universally bad. Nearly every large Rust code base I've seen uses reference counting (both `Rc` and `Arc`) a lot. Moreover, it is not practical to write general-purpose code avoiding both GC and RC because the need for shared ownership will inevitably crop up at some point. So ruling it out as code smell is a bit dogmatic.

It is also worth noting that ownership semantics is one approach (among others like GC) to memory management. In future, more languages will have some sort of ownership semantics along with GC. Nim's ORC is currently a good example.


Let's keep this on track; we're only talking about the learning curve here.

Nobody here is saying c/c++ or rust is better after their respective learning curves. No need to be defensive, they're just languages, and every language has its strengths and weaknesses.

To the point: modern c++ is easier to learn nowadays. shared_ptr and unique_ptr are as easy as Rc and Box, but without the borrow checker making things harder. One doesn't have to deal with the decades of difficulties when learning c/c++. One can choose to dive into a terrible legacy c++ project just like they can dive into an unsafe mess like Actix, but thats hardly a reflection on how easy to learn a language, just the codebase you're learning from.

And rust's front-loading of problems is a great thing! It also makes it harder to learn, which is the point here.


I think we're working from different definitions of learning curves. I include in the learning curve understanding your memory ownership model, not introducing use after free, heap corruption or other failure modes.

I would argue that if you don't understand the ownership of your data you don't really understand C++(or C) and you're still learning the language. That's usually the big shift I see when developers who have a background in higher level languages moving down to C++. I've seen plenty use after free and heap corruption happen in C++0x11 and onward codebases both staying completely within modern best practices and when code diverges since there's no guardrails(ex: std::string::c_str, std::unique_ptr::get and the like).

Once you include all the footguns that exist(yes, even in modern C++) and the legacy parts of existing codebases or code that diverges from modern C++ that's why I think it has a much higher learning curve to be producing code that is at the same quality as a passing compile from Rust in aggregate.


That's reasonable; one's threshold of "safe enough" factors in.

If one is just designing a game, or a command line tool for internal use, one needn't make it completely rock solid, and C++ has the better learning curve.

If one includes the requirement to make it safer, Rust has the better learning curve.

And then if someone actually values memory safety, they use a GC'd language and laugh at how many engineer-months and proofs it will take us to make code as safe as theirs. Sigh, such is life...


> I'd offer one exception though: mutability xor aliasability on a per-object basis is something I wouldn't take to my C++ code.

Rust has "interior" mutability for when you need mutable access to shared data. It works very similar to the "mutable" keyword in C++ except that it's always type-driven, as opposed to something being specified as part of a declaration.


Agreed! While it's not considered "idiomatic" Rust (from all my conversations on the Rust discords), I think that interior mutability is a totally fine thing to reach for in certain cases, at the upper levels of one's architecture.

But then, once your code has RefCell<> everywhere, you're incurring runtime overhead, at which point one might as well switch to a language that makes those tradeoffs easier to wield.

This'll get even better in the near future; a lot of languages are improving in this regard (Cone, Lobster, etc).


> But then, once your code has RefCell<> everywhere, you're incurring runtime overhead

The runtime overhead is quite trivial (a single word per object IIRC, which is accessed w/ simple increments/decrements/checks as needed) and work is ongoing on abstractions that don't incur any hidden overhead (called 'GhostCell').


The runtime overhead of RefCell<> is usually accompanied by some other runtime overhead. To be reachable from multiple places, it usually needs to be stored in some relatively central location.

If it's a rather short-lived object and we don't need to reuse its location, it can be in a Vec, which involves bounds checking and O(logN) calls to malloc, which is not amortized. Sometimes we can put short-lived objects in an arena, which is the best option, but they are very memory hungry, which has its own costs.

If it's longer lived, we can use a Vec with indices or a type-pool, but we risk use-after-"release", which can be a privacy risk and defeats some of the nice "sanity" properties of Rust code (this is still a good option in some cases, IMO).

If it's longer lived, and we don't want those drawbacks, we have to fall back on something like Rc or generational indices, which both have their runtime costs.

IME, only a very specific kind of use case can avoid any of this runtime overhead. When you get to the more complex use cases, especially with lots of unavoidable state, these overheads appear more and more, and make the whole situation a little less clear-cut.

(This was a rather hand-wavy explanation, I can make it more accurate if you'd like)


We can probably all agree that about half of C++ needs to be eliminated or redesigned.

We probably can't agree on which half. :-)


That's what Rust is.

No, not literally.


> The biggest barrier to adoption, in my opinion, is that people are scared of learning Rust because it has a reputation as being difficult.

I would say the biggest barrier is developers not wanting to jump on yet another "this language will solve all your problems, trust me" train.

My experience in my 15 years in software, is that good developers solve problems, not languages or tools.


The languages available today are a vast improvement over what was around 15 years ago. This isn't even all that specific to Rust, even many languages which existed back then have improved massively.


Many of which still have some catchup to do regarding Delphi, C++ Builder, Eiffel, Smalltalk and Common Lisp.


I really like Tony Hoare's quote on this topic:

    ... a programming language designer should be responsible for the mistakes that are made by the programmers using the language.
    [...]
    It's very easy to persuade the customers of your language that everything that goes wrong is their fault and not yours. I rejected that...
http://blog.mattcallanan.net/2010/09/tony-hoare-billion-doll...

If anyone is unfamiliar with Tony Hoare he's the creator of quicksort, Hoare Logic, CSP, worked on Algol, created null, holds a turing award, and much more.


>> My experience in my 15 years in software, is that good developers solve problems, not languages or tools.

At 15 years I thought the same. At 25 years I have come to really appreciate some tools ability to help.

There are a lot of tools that claim to help but don't. Beware of tools that try to manage complexity - what you probably need is to reduce complexity. I'm looking at Eclipse and Matlab in particular, and anything similar (think enterprise software).

Git - awesome. Using it on 1-man projects too.

Sanitizers for C++ I've seen these identify bugs that hadn't manifested visibly yet.

Rust - well I want to write more because it doesnt require additional tooling to write correct code. Remember reducing complexity.


>>> good developers solve problems, not languages or tools

>> At 25 years I have come to really appreciate some tools ability to help.

I've come to find there is a bidirectional connection between good developers and their tools. Good devs recognize and gravitate towards systems that help them thrive, and away from painful ones. Good tools draw in good devs, and the community gets stronger as a result.

IMHO, One hallmark of less-than-stellar devs is a tendency to stick with tools they are familiar with, because "it works." Great devs could get by with a magnetized needle and a steady hand, but they know there is better out there.


Languages and tools have helped people write better software over the years, no?


>I would say the biggest barrier is developers not wanting to jump on yet another "this language will solve all your problems, trust me" train.

Never underestimate what a team of overly enthusiastic junior engineers are capable of :-)


There's got to be a middle ground somewhere. I've worked in many places where the tech stack fossilizes because the ROE of learning how to use new, more productive tooling is too much effort for the senior devs compared to their existing responsibilities, many of which are non-technical in nature.

Meanwhile the junior-intermediate devs spend most of their working hours writing code, so they are extremely sensitive to the 5-10% productivity bump that could be gotten by using {nicer language, better build system, static analysis tooling/sanitizers, ${TOOLING_IMPROVEMENT}.

I'm talking real advances in productivity. Imagine working on a C++98 codebase today in 2021 because you're working on a very large industrial product that's been around for decades. It can be demoralizing, like having to write COBOL or FORTRAN.


Right, it’s not like Rust has already influenced improvements in other languages and package managers. Definitely a fad


Making other languages take affine times more seriously, I agree.

Package managers, which ones?

Perl was the very first, almost every language has their own, and even the growing C++ ones are able to use binary libraries on their package managers.


Among package manager + build tool devs I know, cargo is considered by most I know (maybe 2-3) to be best-of-class.

In terms of influences, here's an OCaml attempt to replicate cargo (I wish them well): https://github.com/OCamlPro/drom

Klabnik also mentioned Python's poetry below. Yarn as well, since Yehuda Katz was involved.

Note: I seem to recall you're an Ada dev, so I should mention that as far as build tools go, I've always really appreciated gprbuild, which is far superior to other build tools of its vintage. If it had a built-in package manager like cargo, it could compete with cargo.


So good that Google is not using it on Android, nor Fuchsia.

I like Ada, but no not an Ada dev, rather JVM/.NET/C++, I rather go polyglot.

And in this regard, while cargo is nice, I don't see how it is better than Maven (I don't suffer XML allergy), NuGET, vcpkg/conan, specially because it only does source packages with npm like levels of dependencies.


Yeah, I almost changed that "Ada dev" since as a polyglot dev, I figured you'd correct me. What I meant was that you had significant Ada experience (or I'm confusing you w/someone else).

Anyway, yeah, Maven is very good and competes with cargo, as well. I agree.

Nuget? Absolutely not, based on my previously undefined rubric. Unlike Maven and cargo, it's just a package manager unless it's recently been expanded (I'm not much of a Windows guy, so not sure). With some pretty crappy defaults as of a year or two ago. No idea about vcpkg or conan.

(I probably should have specified that I'm comparing among package manager that include build tools - or vice versa).

Edit: I suspect cargo will get around to binary packages at some point, as soon as that limitation is resolved in rustc using something like TUF. cargo has not been around nearly as long as Maven.


Btw, I'm also a polyglot dev. I've never used rust professionally (unlike say Ada), but I do really appreciate cargo.

And for the record, despite my love for functional programming, I also have a strong appreciation for Java (not as much as Ada, but it's a great language when used by competent devs).


Rust's package manager has many great features, but it went the other way around. Mozilla hired one of the authors of rubygems and yarn to re-implement their better ideas.


This is true, but so is the grandparent. Poetry, for example, cites Cargo as an inspiration. build2 describes itself as something "that aims to approximate Rust Cargo's convenience for developing and packaging C/C++ projects." I believe Go's "dep" was Cargo inspired as well, though that didn't work out.


Yarn came after cargo was started, I'm fairly sure.


> Package managers, which ones?

Python's Poetry comes to mind.


>> backend web development

>> thread-safety

In 2021 what web development stack is making you write threaded code?

>> correctness that matters

The compilers guarantee end at the edge of your processes address space. You still have the same big problems as everyone else:

  1. Are you building the right thing?
  2. Does everyone understand the domain adequately to do their job?
  3. …
  101. Do i have a race condition
Except you have a self-inflicted problem - you’re slower than a dev team working in a traditional language (java, go, python, …) and you can’t easily hire talent.


>> you’re slower than a dev team working in a traditional language (java, go, python, …)

If anything my experience is that it's quite productive to work in Rust. For example, compared to Python (which you mention) we catch bugs earlier (with the compiler) rather than later (system test) and so development is faster. Shift left.

It's particularly important for races because they are some of the most difficult bugs to find and fix.


> Except you have a self-inflicted problem - you’re slower than a dev team working in a traditional language (java, go, python, …) and you can’t easily hire talent.

I'm radically more productive with Rust vs Python (having been using both for >5 years). Our codebase is split between the two and I'm working to move virtually all Python code to Rust because it's become such a burden.

* IDE experience is considerably worse in Python due to lack of types (we use type hints aggressively, but that only helps so much and not at all for 3rd party libs).

* Working with JSON is considerably worse in Python in my experience.

* Package management and building is considerably worse in Python. It's still difficult to manage a many-package project and get what Rust provides by default, like workspaces, cryptographic lockfiles, etc.

* Error handling and other patterns in Rust make it far easier to write in a robust way or otherwise correct in the future. Rust is far more resilient to errors during refactoring - I'm very afraid to touch some of our Python code, by contrast.

* Mypy is nowhere near as good as rustc. Mypy errors are traditional "expected blah got blah", or sometimes "expected List[T] got List[<nothing>]" and other unhelpful errors. Rust errors are almost always expressive and helpful - often telling you exactly how to fix your code (to an insane extent - like using a heuristic to tell you where you probably forgot a curly brace).

Mypy is impossible to use with the strictest settings. Lack of recursive types makes working with JSON blobs impossible, makes it impossible to do circular generics (you can't do what Rust does with From/Into as far as I know because of this).

And then there's shit like circular imports being a runtime error, and other little papercuts in the language that are just littered everywhere.

I actually really like Python a lot, despite all of this, but I'll never choose it for web services again.

And hiring hasn't been a problem at all at my company, nor was it at Dropbox where I worked previously


> In 2021 what web development stack is making you write threaded code?

Go? I've had thread related bugs in go related to serving our UI.

Generally any reasonably efficient stack where you need to pull on more than 1 CPUs worth of resources to quickly serve a request. And most stacks where you need to make multiple requests to other services simultaneously to quickly serve the original request.


My very first production Rails app involved a C extension to do some heavy processing. Not all web applications are a thin UI over a database table (not that there’s anything wrong with that, mind you…)

The framework might not make you but that doesn’t mean your code won’t need such things.


Isn't that just self inflicted though? You probably wouldn't have had to write C/threaded code if you chose a faster runtime like C#/Java/Go/Kotlin/Scala instead of ruby.


At the time, Go/Kotlin didn't exist, Scala wasn't established, C# was Windows only, and Java and the JVM more generally were a thing that everyone was running to Ruby and Rails from for lots of reasons. Probably wouldn't have gotten the thing out the door if I had to do it in Java.


> In 2021 what web development stack is making you write threaded code?

Go uses "green" (user-level) threads.


What web framework do you use? This to me seems like the part that's least-baked at this stage. Iron doesn't support async if I recall correctly, actix supposedly has a complicated mental model and was mired in drama last I checked, and Rocket looks promising but is still in the somewhat-early stages.


We've been using Actix.

We evaluated several frameworks and liked the model that Actix has and also its relative maturity (for example documentation / examples). It has been pretty straightforward to work with - including doing things like custom authentication and REST endpoints that dynamically exist.

For the drama, I guess you are talking about the situation that used to exist where Actix had hundreds of unsafe blocks. That's pretty much resolved now, with perhaps a handful of performance critical unsafe blocks left.


For the drama, I was talking about this: https://www.theregister.com/2020/01/21/rust_actix_web_framew...

I'm not passing any judgements, I just know that people were somewhat worried about the future of the project after its creator very publicly washed their hands of it. Sounds like it's still going, which is good to hear


Yes, Actix today is much different than Actix from a couple years ago. All the unsafe, save a necessary few has been removed, and the architecture switched from an actor model, to a finagle/tower inspired service model.


Any references to this architecture? The only finagle I aware of is http://twitter.github.io/finagle/ but it's a asynchronous RPC framework and it's not clear to me how it applies to Actix web.


> and the architecture switched from an actor model, to a finagle/tower inspired service model

Then they really should think about changing their name, seeing as actix the broader low-level framework is supposed to be all about Actors.


A name change would have been ideal, but the library was already mature and widely used that it was decided a name change was not worth it.


Actix the actor framework is essentially dead at this point, I expect eventually it'll be the other way around: "you should change the name of your actor framework, it's confusing given the name of the web framework"


Check out tide. It's still very early days for it, but is in my opinion the easiest to use and I'm betting in the long term will win out as the "express" of the rust world. It has very straightforward routing and middleware semantics which covers the majority of the "base" needs for most web server backends.


We use hyper + tokio directly, with OpenAPI generated API integration.


> I don't think it's any harder to master than some other major languages such as C++ or Java

But this is backend web development, the major languages are more like ruby/php/python/js/java. You might write a C++ extension as an endgame move, but for webdev it's never an opening move.


Training internally makes a lot of sense, but it's also a huge hurdle and expense if your developers don't already have rust experience.

What was the process of proposing rust and getting buy-in like?


We initially used it on a small project that had the requirement that the chances of a crash / failure should be very low because it would be used as a remote control process for a wider system. We had good success there and so the company was keen to use it in more places. It's now formally "adopt" on our technology roadmap.

We've actually bootstrapped relatively easily. We have a some developers who have picked it up quite easily, perhaps with some pairing. We run an hour session every week where all the Rust developers get together to share production code and present on Rust topics. The discussion focusing on Rust production code has been particularly helpful.


Rust is really hard to learn though. the compiler errors are hard to read and understand, it's an extremely syntax heavy language. I used to work with someone who regularly contributed to rust, I had some errors on a project that confused him too. The only other times I needed to a book to learn a language was Scala and haskell, both hard to learn languages.


Picking up Rust is not the same as picking up Python or even Java, in my opinion.

I started learning Rust and C++ at the same time, coming from a world of Java, Python, and Ruby.

If I need to solve a problem in C++, I would much rather write Rust because the compiler actively screams at you when you do bad things.

And in my opinion, the challenging part is learning what those bad things are. In other languages, the compiler doesn’t care. You immediately see your program crash or things fail in subtle, hard to reproduce ways later in production. Rust changes that model.

I disagree with you on the documentation. I think the Rust documentation is superb. I have yet to see any language give nearly as meaningful information when your code fails to compile. Secondly, Rust front loads and throws issues immediately in your face, as opposed to having you discover problems in your code at runtime. I don’t think that makes Rust difficult - it’s forcing you to think about your choices. And particularly it’s making you think about concepts that perhaps you completely overlooked in other languages - thinking about stack vs heap allocation, moving semantics, shared ownership, etc.

If you want to quickly prototype something, Rust isn’t the best language IMO. But if I have a choice between C++ and Rust, I’d go with Rust anyday. If I was starting a new project from scratch and it was more of a web service, I might go with another language over Rust only because I’m more of an expert in Java, Python, etc. and it’s easier to hire developers for those languages than Rust.

But I’m biased. Rust has a special place in my heart. It’s the first language I’ve learned in many years where I felt some sense of accomplishment and did not at all feel like “Oh great, another tool that fundamentally doesn’t add value.”

For my use cases involving Java and iOS interoperability in a multi threaded environment, nothing else came even close.


I think your kind of discussing the positives of rust, but despite all that still rust is a lot of work to learn. The learning curve of rust might be worth it, I just didn't agree with the statement that rust isn't actually hard to learn.


Please file bugs for hard to understand error messages! We treat them as such. We’d rather have too many reports than not enough.


What a perfect example of developers pushing for technologies they want to learn. A web application stack in the flavor of the month systems language for correctness!

My eyes can’t possibly rollback far enough.


This "flavor of the month" language was released 10 years ago and has been the most loved programming language in surveys for several years now. It is also the language of the fastest backend web framework.

I don't think rolling one's eyes is the appropriate reaction when someone pushes for it. Depending on your requirements, there are definitely cases when rust is the best choice for a web backend. Especially when moving fast and breaking things is not an option, such as in the author's case.


Can you share details on what material you used for the internal training?


Most people are happy to teach themselves the basics through some reading of https://doc.rust-lang.org/book/ then a mixture of pairing, code walkthroughs and short presentations.

We will also run a training course next month just based on the Rust book plus some workshop examples.


Any reason to choose Rust over Go in your case?


A couple of reasons: 1. We like the thread-safety properties that Rust offers 2. We don't have any Go experience

Does Go offer similar guarantees for concurrency?


Go doesn’t offer the same sort of guarantees as Rust does, but the goroutine/channel model nudges you towards a safe style


Go is memory safe for purely sequential code. It's not memory safe to share memory-write access among multiple Go threads. Using CSP idioms only, via Go channels, can preserve memory safety, but is prone to more general race conditions.


Although better, Rust can only protect against races coming from threads accessing in-memory resources.

For races related to external resources, or caused by misuse of OS IPC mechanisms (which is the future thanks Spectre), it offers as much protection as any other language.


Go does runtime instrumentation to detect data races, rather than compile time checks.


I’m at a company where we have tons of Java services. Services scale out horizontally, are fronted with load balancers, and there’s some minimal JVM tuning. Some services have thread pools dedicated to making calls to other services. Aside from that, there isn’t that much multi threaded code that we’ve had to write. Throttling is in use as well.

I see a big Rust benefit when you’re writing systems level code or you’re writing once and use the code as a library on Android and iOS.

But what type of logic are you writing in your services that requires Rust’s safety guarantees? Or is it that you’ve found you can respond to the same performance metrics (total requests per second) with fewer hosts because there’s no JVM or garbage collection overhead?


We are building openapi-based stuff in Rust at Oxide, and my coworkers gave a talk on the hows and whys: https://www.youtube.com/watch?v=EmSjZbSzA3A

One thing I hear from people more broadly is that Rust’s lower resource usage, in today’s cloud based environments, translates directly to bottom-line savings. It’s not so much speed directly as it is less CPU and memory utilization, letting you do more with less. That matters when you’re paying for what you use.


That was an interesting presentation, thanks for sharing


The DB space for Rust is a bit young, though there are several good projects like sqlx making it much more pleasant.

Rust shares many of the benefits of Go:

- statically linked binaries for ease of deployment

- good concurrency

- builtin testing framework

But it's a much sharper tool than Go:

- Really great error handling with Result/Option and the ? marker

- Like, really really good error handling, esp compared to Go

- Very pleasant logging and tracing

- Serde is fantastic at automatically serializing/deserializing datastructures

- Generics make Map/Reduce/Filter really easy and readable

- Really good project management through modules/Cargo.toml

- Crates.io is like NPM - really discoverable and easy to upload (with its goods and bads)

- FFI with Swift, C, C++, Node, etc to share code everywhere

- Builtin documentation

- Builtin benchmarking

- Powerful hygienic and non-hygienic macros

There's a lot more. I would say people choose Rust over other web frameworks not because of the language, but the emphasis on great tooling. Being able to test, document, benchmark, deploy, package, with a language that feels like a child between Go, JavaScript, and C++ is very attractive. Plus, it's fast - like really fast - and it's really obvious where optimizations can be made when the time comes.

I've worked a decent amount with Go, but I'm also frustrated with the size of projects balloon. When I compare my Rust and Go code, the Rust code ends up being much smaller (LoC) and much more dense/terse.

I've been working with it for a few years now, and I'm 100% willing to trade some complexity when doing Advanced Stuff (tm) for the 1st-class tooling. I hate having to decide which testing/documentation/building/benchmark/etc framework to use in other languages. I just want to build, not futz around with Jest/Babel/Webpack/Poetry/PyEnv/Opam/CMAKE etc.

If you're looking into using Rust for web, I recommend https://github.com/http-rs/tide - it's the most pleasant web framework I've ever used.


I personally prefer Rust to Go for things that have hard resource requirements/limits, but there’s no denying that Go is much easier to program than Rust.

You don’t need to know much more than Python/Ruby to get something done in Go, whereas Rust needs a C++ or Scala or Haskell or whatever background.

Rust places too much mental workload on a programmer to make the compiler happy.

The Go compiler is much more human friendly.

Swift is a nice mix of all worlds, IMHO. Would be nice to see that get more server-side use.

At our Scala-centric company, Go gets used a lot more for one off tasks and microservices.

We rebuilt one Go service in Rust just to get familiar with it and no one has written more Rust since.


I dabbled a bit with Go and now I am trying Rust. I did find programming in Rust a tad difficult than with Go, but as I get used to concepts (borrow checking, Move vs/ copy, lifetimes etc.) I am liking it better than Go. With Go I feel there is an element of deceptive simplicity, which catches up with you as the problem space gets complex. I never became comfortable with doing object oriented programming with Go, which has not been the case with Rust. In addition in Go I find the project setup and settings like GOPATH, GOBIN quite confusing. In contrast Rust has _cargo_ which has less cognitive overload.

I think it would be good if one dabbles a bit with both and pick one which one feels resonance with. That being said probably one need to give a bit longer time for Rust to be comfortable with it.


> I never became comfortable with doing object oriented programming with Go, which has not been the case with Rust.

Ouch, OOP in Go is just asking for a trouble. "Inheritance" by embedding anonymous struct/interface should be rarely used. Playing with a magic dependency injection, reflection mocking often do not leads to anything good too.

> In addition in Go I find the project setup and settings like GOPATH, GOBIN quite confusing.

I guess you work on Linux :) Yeah, it is weird, I am glad they have improved that flow by guessing empty GOPATH will be equal to $USER/go/ directory. GOBIN is actually not needed, only if you have used dep dependency manager, which for many years is deprecated.


> but there’s no denying that Go is much easier to program than Rust.

Well here I am to deny it. I personally find Go super hard to write anything that is not a few lines of glue code (and in that case I just reach for Node).

Rust made me lazy. It's just so easy to be guided by the compiler and the architecture that emerges naturally is just so beautiful and easy to navigate.

I don't like Rust for its safety guarantees, I just find it pleasurable to write and even better to read. Safety is just a plus.

I'm not saying this is a universal truth though, Rust just fits my mental model. It isn't even a matter of past experience: I code frontend JS for a living (though I've been exposed to all kinds of code throughout the years) and I actually enjoy JS.

I tried really hard to like Go. I just couldn't.


> Well here I am to deny it. I personally find Go super hard to write anything that is not a few lines of glue code (and in that case I just reach for Node).

> I tried really hard to like Go. I just couldn't.

I would expect something opposite for most of programmers. Especially, because Rust support in VSCode/JetBrains IDEs was not very good for many years. However, during talks with various people, I have noticed the Go was natural choice for many former Python or Ruby devs, while Node/Java guys had problem with adapting to it.

Personally, when I take a look at the Rust code it feels like some ECMA Script in a compiled world.


I agree. Go just lets you get away with writing garbage.


TBH I'm kind of frustrated with Swift's lack of dynamic dispatch options, so things like network models, network service interfaces and testing mocks need to be code generated, while in JVM and Objective-C land, you don't need to do the same.

Swift's Codable is doing code gen under the hood, so it also has a binary size and compile time cost.

Swift also doesn't scale that well with core size like many other languages do, so your compile time is not easily fixable with large thread ripper style workstations.

Do you have similar issues with golang and rust? At least golang was designed to be compiled fast.


Rust has similar issues with dynamic dispatch (but you're probably better off avoiding mocking anyway). I believe there are libraries to use conditional compilation to switch in mocks for test builds if you really want them.

Compile times are definitely a pain point in Rust, but from what I've heard the Rust compiler is pretty good at scaling to multiple cores (my machine only has 2, so personally that doesn't help much).


I find it easier to either use conditional compilation or traits for test substitutes. Using dynamic dispatch for it is more trouble than it's worth IMO.


Can you expand on “needs a C++ or Scala or Haskell background”? C++ would probably help you appreciate what Rust brings to the table, but I don’t see how any of them fit in when learning to use Rust in practice.


One way of looking at Rust is that it is kinda at the intersection of three different language families: {Ruby,Python,JavaScript} x {C,C++} x {OCaml, Haskell, Scala}

“Needs” is a bit strong but “may find some things familiar and therefore easier” is a common refrain.


That makes more sense. I'd probably phrase it as: "if you are familiar with a lower-level language and a functional language, you'll likely have an easier time learning Rust".


Yup, I’d agree with that.


Not the OP, but I agree. Also, coming to Rust from a higher level language is very hard. Beginners who do so cannot understand why something like this:

    fn foo() -> &str {
        &String::from("foo")
    }
Does not work. Whereas coming from C or C++, you will appreciate the safety guarantees the borrow checker is giving you.

Learning Rust coming from an OO background is also hard, as you have to adapt to the more functional approach of the Rust type system.


There's definitely content to be learnt. But I'm not sure I'd say it's very hard. I came from JavaScript, and I found that the Rust Book was very good at explaining these kind of issues, so even though they were new to me they didn't cause too many problems.


That makes more sense - it's definitely true that knowing a lower-level language and a functional language gives you a leg up when learning Rust.

As for your example, even C and C++ devs would squint a bit at why that code doesn't compile: you're allocating a string on the heap, so why can't you return a pointer to it? Also, I think str vs. String is usually confusing at first, regardless of your background.


I think analogous C++ code is a bug, the text might be a heap allocation (SSO may stash it inside the object) but surely the string object is local and lives on the stack. When the function returns that local object no longer exists and the reference to it is now dangling ?

I would say that the relationship between str and String was what most surprised me. I at first assumed the underlying primitive would be String since str is what you get when you borrow from a String, but it isn't. str is a built-in, whereas String is just a type defined in the (optional, this is a systems language) standard library.

If your environment can't afford memory allocation, you can't have Strings but you can use str just fine, that's a built-in. Since you lack allocators obviously you won't be going around minting new strings but str is perfectly fine for stuff like substring operations or comparisons.


> Also, I think str vs. String is usually confusing at first, regardless of your background.

Yes, of course. Rust has some new concepts that will be confusing at first, regardless of your background. You still have to understand Rust's destructors to understand that example. I didn't mean to say that it is impossible for Rubyists to learn Rust, or that C++ devs would understand Rust immediately.

Perhaps a better example:

    fn foo() -> &usize {
        let x = 50;
        &x
    }


From my experience I found the ideas of move semantics from modern C++ directly relatable to ownership and move vs borrow. I also found the FP ideas from Scala, pattern matching, combinators, result and option monads directly useful in rust.


I would have said it was mor like ocaml.


> When I compare my Rust and Go code, the Rust code ends up being much smaller (LoC) and much more dense/terse.

Yes, but is it more readable too? The obfuscated C contest also tends to produce a lot of dense/terse code, but you probably wouldn't want to use that in a production system...


In my experience, Rust code is relatively easy to read, even by developers with no Rust experience.

Of course, you can write hard to read code. But that's not typically what comes out of a process of writing production software.

That's not to say that someone with no experience will fully understand the ownership transfer & borrowing that's happening, but that's just stuff you need to do for the compiler. Reading code that already compiles, you can mostly ignore that and focus on the program logic.


Yeah, readability is high, it's writing that can be a bit harder IMO.

Especially for someone unfamiliar with rust, it can be hard to really know why someone is using self, &self, or &mut self. Yet the code reads the same.

That's the funny thing about rust.


The compiler is supposed to tell you when you get it wrong. This does leave design issues on the table, but it's also good for those to be addressed explicitly, by the more senior people on the project.


Rust is one the hardest language to read. Take two people that never used Go or Rust and make them read code, good luck with Rust.


So I have opened golang.org:

v1, ok1 := <-c1

Not sure what is difference between := and = and what is that arrow. But if I'm going to do something with the language - I guess it will be easy to find out. Like with Rust.


Sure - except that in Go there are (my impression after taking a look at various Rust resources) far fewer things you have to find out this way than in Rust. Which, of course, some view as a limitation, others view as a plus for Go.


I'm a newcomer to Rust, and find it relatively easy to read, at least at the level of "what is this code doing?" (Not necessarily "why did they need to specify lifetime there?")

The major exception to this are cases where authors use macros to invent their own DSL inside Rust code. This sort of thing seems common in the Servo codebase, amomg others. It reminds me of C macros or Python metaprogramming magic, both of which directly led to some incredibly difficult past debugging experiences.


It depends on what you're trying to read. If you want to understand every technical detail (e.g. who owns this variable) then Rust is great. If you want to understand the business logic behind it (e.g. under what circumstances is a customer allowed to return that product) then Rust is not so great as you would have to mentally filter out all the technical noise.


Map/Filter/Collect/Reduce, all built on generics make code much more readable than their Go counterparts. I can make a frequency map simply by drain and collecting a vec into a hashmap - maybe 4 lines of code.

The density comes from being able to share common functionality behind generic interfaces, so I don’t have to reinvent the wheel for every new project.

I find that most projects I make look the same internally, unless I start pulling some “clever” optimizations like custom allocators or self-referential structs.


"good concurrency"

Async rust is very messy and a pretty big issue atm. The tooling on the IDE side is subpar compared to Go.


To write custom futures? Yes, you need to understand Pin and some advanced stuff.

To use? Eh - I just turn on async_std with the Tokio flag and write go-like code with async tasks. No issues thus far.


What's the deal with cancellations? If you're coming from Go, the context package makes it convenient to do.


Funny you mentioned the context package, as it was pretty hacky way to work around the cancellation problem.

There are some pain points with cancellation in Rust. Dropping a future cancels it, but that requires ownership over the future, and may cause unexpected behavior due to the nature of futures state machines. This, along with many other issues, is being discussed by the async working group: https://github.com/rust-lang/wg-async-foundations/issues/65. If you have specific suggestions, or a problem that you faced, please open an issue! It is really appreciated - async rust's problems cannot be solved without community feedback and engagement.


I switched to rust-analyzer and it made a huge difference. Have you tried it?


I'd be interested in hearing what you think is a problem in async Rust.


I'm not the one you responded to, and I haven't used Rust much myself, but one of the issues I've seen raised several times is that its async ecosystem is fractured. You have to select an async stack, and sometimes different libraries and frameworks use competing stacks, causing problems.

It's not like JavaScript or Go where everything is just built into the language afaik.


There’s been a decent amount of standardization on top of Tokio’s implementation of async (green threads). If a library didn’t support it at first, they probably now do using features in your project.toml requirements.[1][2] That said, I agree the standard library isn’t the size or utility of Go’s nor is the ecosystem as wide as Go or npm.

Personally, I’m looking forward to the next few years when more and more companies reveal what patterns they use with Rust development. I think Rust is missing the kind of boost that Rails gave Ruby, for example, or that TypeScript and React gave Node/SSR. Or that Pandas gave Python.

1. https://doc.rust-lang.org/cargo/reference/specifying-depende...

2. https://doc.rust-lang.org/cargo/reference/features.html#depe...


Your reply has piqued my attention, because as a person who develops in Go (and in other programming languages) I cannot put any > or < between Rust and Go - they are clearly tools dedicated for other type of applications.

I won't try to play as a Go devil advocate, because I don't feel good enough today to start such discussion.

What is the worst thing I have experienced in Rust? Lack of good packages, especially if we speak about cloud stuff (rusoto and google-api-rs). Human resources put from cloud providers are very scarce. As longer I dived into the Rust the more I felt I am alone freak, because I had to work more hours to achieve the same result as in Go, PHP, Kotlin, TypeScript, C#. My use case of Rust was a GraphQL gateway (gRPC+HTTP) and after few weeks of idea verification the project was dropped. Mostly because instead of developing business logic the team was focused to implement own libraries for Google Cloud and other SaaS offerings on their own. Ridiculous, but Mozilla devs [0] went the same way by taking the whole job on their shoulders and they were generating subsets of APIs, because they cannot find any good, official libraries. It is frustrating and time consuming making Rust completely no-go for many teams.

> I've worked a decent amount with Go, but I'm also frustrated with the size of projects balloon. When I compare my Rust and Go code, the Rust code ends up being much smaller (LoC) and much more dense/terse.

I can exactly the same about the Rust. I think it was not the problem with tool but with something between chair and keyboard. I had a pleasure to see and refactor very bad Go code and actual ballooning was never a case if you have applied Clean / Solid architecture. The "ballooning" was actual something nice, because anyone in the team could pick the repository and take care of implementing new business logic.

The number of lines of code is quite bad metric for Golang, because famous "if err != nil" takes a nasty 3 lines, while in many languages you can write it using single liner. In my humble experience, the number of lines of most Go web apps can be often compared to TypeScript apps. Also many web apps that I have developed usually had hefty 2-5k LoC and it is not bad result if we consider C# or Java web apps.

> - Powerful hygienic and non-hygienic macros

Yeah, having marcros in Rust is a gem.

> - Builtin benchmarking

Same as in Go. See testing.B.

It is weird you have pointed out

> - Builtin documentation

Same as in Go. See godoc.

> - FFI with Swift, C, C++, Node, etc to share code everywhere.

I rarely see the case for FFI in web app - I don't imagine even using it like that. It was common case for chart, TeX document or other web to image rendering to embed some library. I think it is a bad approach and the best currently is just run that code as separate binary, because it helps in maintainability of a third party dependency and your devops teams will love that decision.

As a person who rewrote the rxi/lite [1] to Rust I can only say I am terrified how many times I had to sacrifice having unsafe calls to just use some C code in my Rust application.

> - Crates.io is like NPM - really discoverable and easy to upload (with its goods and bads)

Personally, I feel Go/Deno/Docker flow of the installing dependencies is more convenient. I don't project names that do not sound what they provide. Naming thing is bad and I often see many developers are scratching head to find some unique name, so it could be easier findable in NPM or other repository. They are wasting time at looking for something short and funny and not something that is easily discoverable.

For many years, my only way of looking for dependency is GitHub. It helps to verify and investigate the quality of the code before adopting it in the application. It sometimes also results in contributing back to the project, because I already know where the project is located.

> - Really good project management through modules/Cargo.toml

It is really complex I'd say. But Cargo.rs would be nice to have :P

> - Generics make Map/Reduce/Filter really easy and readable

Matter of time in Go. :)

> - Serde is fantastic at automatically serializing/deserializing datastructures

Oh, that's true. Go has numerous serializers (for only JSON there are about 20+ nice looking implementations) and it is still interesting to see new ones, especially because they bring many non-obvious optimizations. Kotlin serializer is also top notch thingy. I recommend to use protobufs types in Go - even for domain models. It is interesting how with Go2 can improve the situation.

> - Very pleasant logging and tracing

The log package is nice, together with macro log! is really pleasant to look at it how concise it is to fill some context parameters around the message. I think it is like Logrus in Go, except the syntax it has the same features. There is also Zap package that sacrifices readability for performance. There is no problem to embed number of line of code, calling function in Go logs either.

Tracing? Yep, it feels the same for both languages I think. I had used OpenTracing (Jaeger) and I hardly can say I miss something from one or other language. Maybe some macro/annotation wrapper that will be added on compile time? However, I rarely see any use case right now for complicating such thing like tracing.

> - Like, really really good error handling, esp compared to Go

Hey, it is not that bad! :D But well, as long as you use Goland you don't care about the if-err-non-nil.

If you switch for few days to Java-world you will be like in hell after developing in Go, because the error-over-exception flow is really helpful to provide code that does not have any kind of error and you, as a developer, can guess what happens in specific line without any println("1") or debugger. Monads are nice but I will not trade current if-err for them.

> - builtin testing framework

AFAIK all modern programming languages includes some testing framework: Kotlin (kotlin.test), Zig (std.test), Elixir (ExUnit) etc. I am glad both Rust and Go joined that club.

> If you're looking into using Rust for web, I recommend https://github.com/http-rs/tide - it's the most pleasant web framework I've ever used.

It is interesting, but I think even today there is nothing that I could label as a "framework" in Go world. You wisely choose the best packages matching your needs. The situation has improved with many libraries providing a GraphQL endpoint.

> I've worked a decent amount with Go

Reading your post, made me think you don't have good Go experience and it sounded bad IMHO. I guess you had nobody proficient enough in production-ready Go apps to evangelize it within the team or there was no reason to use Go (yep, it is not a perfect tool). ;)

[0]: https://github.com/mozilla-services/syncstorage-rs

[1]: https://github.com/rxi/lite


I implemented a simple blog and resume personal web site using rust. I did it mostly as an exercise. I tried just jumping in and had a lot of trouble. I needed to go back and read the rust book. What I found was relatable to what I knew from Scala and C++ but definitely took some effort to learn compared to something like golang which I picked up in a week.

I built using actix 1.x, serde, chrono, rusqlite. I originally tried diesel but it doesn't support certain relationships that are common in SQL. I made my own traits for common CRUD and ORM patterns but I'm not happy with the amount of boilerplate code needed to implement them. I could clean them up with macros but I'm still rethinking the approach.

I did implement my own (unpublished for now) crates to output jsonapi formatted messages and handle uuid primary keys in sqlite, serde from the DB and json.

Overall I'd say it's comparable to coding a web app with C++, but perhaps more straight forward. I added my own middleware for Google Auth without much trouble. It definitely seems to be a "if it complies it works" type experience.


Coding a web app with C++ Builder is like dragging stuff into forms, VB style.


I use Rust because the program I am writing mainly maps types from type A to type B.

A dynamic language has no clue what these types are so you find out what you did wrong by refreshing the app at runtime.

In Rust it tells you instantly, so it reduces the iteration time.

Many web apps fit this “map data from A to B” domain, so having a specification for types A and B and getting the compiler to check all variations seems like it would save a lot of dev time.

Out of the type systems available I like Rusts best as it seems to map well to JSON using its enums feature to represent null or polymorphic types.

But you need to pay the learning curve of Rust, which I am still not sure it is worth it.


Rust makes working with data easy. 'serde' is insanely good, so right off the bat if you're messing with formats like JSON you're going to have a best in class library.

Concurrency is pretty trivial as well with async/await and tokio.

Really good libraries like tracing, tonic, etc.

Plus the tooling is really strong. Package management and building is easy, static bins, etc.

I run a company that uses Rust and hiring isn't hard - it's an advantage. We get really great people who are looking for a place that uses Rust. Or we just train people up - it's not a very hard language.


Both matureness of the ecosystem and developers are a big issue. For typical enterprise apps you just don't need the characteristics of Rust and therefore it doesn't make any sense to pay the penalty for using it. If your focus are business logic related needs (as opposed to best in class performance, no GC, etc.) using Rust is a grave mistake. Just use boring Java or better Go (better tooling, standard lib and scaling) and focus on delivering value to the customer.


If you were coming from Python/Ruby then the speed boost of Rust might seem like it is worth it, but if you are coming from Java/C#/Go/F# I agree it is a hard sell for a normal web back-end. But if you have one that is compute heavy, it could be a great fit. If you want to use mostly WASM on the front end, it could be a great fit as well. Don't have to ship a runtime with your wasm, and can share code.


I’ve been using Rust for 5 years for REST API and the most important thing is the safety of refactoring. Not memory safety, not speed, but errors handling and safety of refactoring are key features for web backend. Also, things like Cargo and ootb testing framework - are quite valuable.


Rust has one of the best toolchains for Wasm.


It helps in RDD (resume driven development)


It's a bit early for Rust to be widely applicable to web development, because common web backend frameworks require nightly Rust which is not appropriate for production. But most of these nightly dependencies are being resolved.


That's no longer the case. There are many web frameworks working on stable, and Rocket, which was one of the most popular nightly-only backends, has been building on stable for nearly a year now!


With the caveat that you have to use _nightly_ Rocket straight from GitHub (but still stable Rust, which is definitely preferable).


They're working on it but they don't have an actual released version that works on stable Rust. So you'd end up having to pick stable Rust or stable framework, which is not great.


Ad for a £35 book.

"Zero To Production will focus on the challenges of writing Cloud-native applications in a team of four or five engineers with different levels of experience and proficiency."

It's useful for that. It's not about how to program in Rust. It's about how to set up a production web application in Rust. This is more of a tooling problem.


If you visit https://www.lpalmieri.com/ you can read the chapters before buying and supporting the author.


This looks really great.

£35 Individual, £100 Team, £600 Company, seems like fair/straightforward pricing for a team that has members who know some Rust but haven't built out a production API with it yet. I wish every tech stack had a book like this, and I think it'll be particularly valuable for an exciting new language with a learning curve like Rust.

I will note, though, that I'm currently consulting on a team that's transitioning away from Rust for their startup's GraphQL backend because they found it too slow/difficult to onboard more junior engineers to the language. Personally I find the Rust code pretty great, but the learning curve (and perhaps even talent cliff) is something to keep in mind if you're considering Rust for a standard web api use-case.

TypeScript is probably a more appropriate choice for most situations – still a rich, powerful type system, great performance, and much faster compilation times (and thus iteration speeds) and much, much easier to find engineers who will be productive within a month on your codebase.

EDIT: To be clear, I still consider myself a fan of Rust, and am keen to have an excuse to use it.


I have been involved in training several "junior" devs in Rust and I would say that it's more about their ability as a developer rather than them being junior.

Developers who could get by professionally in Python, but were not particularly good, have struggled with Rust.

However, we have several developers who joined us directly from their undergraduate degrees who have picked up Rust extremely easily.


> TypeScript is probably a more appropriate choice for most situations – still a rich, powerful type system, great performance, and much faster compilation times

Compared to Rust's normal debug builds Typescript does not have any noteworthy compilation speed advantage in my experience. In fact I find incremental Rust builds very similar if not faster in some cases (of course there are extreme exceptions both ways; I've used a library that added 40 seconds to every Rust build, but also frameworks that didn't make a noticeable difference after the first build). Meanwhile the quality of TypeScript error messages is much worse. Also sometimes debugging gets confusing because TypeScript has a couple blind spots and in the end it still turns into JS with all its quirks. I find Rust's type checker significantly more precise and comprehensive. On the other hand TypeScript doesn't (need to) care about things like pointer ownership, so often there's much less to worry about.


We can cheat Typescript builds by using a different tool to strip the types, and generate type errors on a different thread. The type errors can be terribly slow, and the build times quite fast.


at my startup, we built a graphql server in elixir and its been great. very easy to onboard contractors and the language is very straightforward. https://absinthe-graphql.org/

The performance has been excellent compared to similar offerings in django and rails while having better dev productivity than the equivalent nodejs libraries.


Wouldn't Golang be the TypeScript here as alternative to Rust ?


Why? Golang has a much less advanced type system, comparable runtime performance, a smaller developer community, and a smaller package ecosystem.

Plus, if you're building a backend for a webapp, TS allows your engineers to build full-stack features in the same language, avoiding context-switching, code duplication, and other overhead.


I accept all your points, but comparable runtime performance? That's the only reason that people away from node/ruby/python towards gaoling.


I recently rewrote a computation-heavy Typescript program in Go and what once took 12 hours can now be done in about 3 minutes - there was also some trickery involved running things in parallel but Go made that possible, trying to do that in JS just froze my computer.

Plus it’s a binary I can drop anywhere, will always be backwards compatible, no updated dependency is going to break it, I’m a fan of Go.


As far as I know, after Node.js/V8 the only reasonable performance gain comes from switching to Rust/C/C++. Everything else is just a few % faster, not a magnitude.


Turns out I hadn't heard of go's fiber framework, which performs impressively on Techempower's composite benchmarks (just behind the top ten dominated by C++, Rust, and .NET Core, and barely ahead of Java).

Other than Fiber, the techempower composite framework benchmark[0] ranks gin (go), nodejs, clevergo, and fastify (node) one after the other, all scoring right around 1600.

To be fair, Express is half that good at ~800, but upgrading from express to fastify should be fairly straightforward for those seeking better performance; the much newer fastify has a similar (often compatible) API.

For comparison, Python's fastapi is only 1200, and Django/Rails a mere 250, so lumping Node in with Python and Ruby doesn't make much sense; it'll often perform an order of magnitude better.

For computation-heavy workloads, multiprocessing with Node remains a challenge; Go's a more clear winner there.

[0] https://www.techempower.com/benchmarks/#section=data-r20&hw=...


"difficult to onboard", yeah why not if your juniors are not self learning. But "too slow"? What?!

Edit: oh I get it, "too slow" as in "compilation time". I guess they really needed excuses to move back to another language.


I think "too slow" is "too slow to onboard juniors", not "too slow in terms of performance".


Correct – it took about 6 months for people to become fully productive in Rust, which matches what I've heard elsewhere.

Though I will note that the Rust compilation times were also far more painful than I'd expected – even the tiny (~5k sloc) app at hand would take what felt like a minute to recompute the red squigglies in my editor.

TS felt slow if it took 5-15sec, and Sorbet (for Ruby) was usually <3sec IIRC, so a minute+ was pretty bad.

Rust was in the realm of "just don't use this language if you have ADHD" since you really can't make progress without the compiler's exacting approval, and I'd constantly get distracted while waiting.


Make sure you're not using `cargo build` to check your project. `cargo check` (the thing that makes your squiggles red) has never once taken me a minute to complete. RLS (the default LSP for rust uses `cargo build` - definitely switch to Rust-Analyzer (the soon-to-be default). I just ran `cargo check` on my workspace (10 crates, about 5k LoC) and it took 3 seconds.


My mistake! Replacing RLS with Rust-Analyzer, it now takes 20-30s to incrementally check a trivial change to some core model code (compared to ~90s with RLS), though now rust-analyzer gives me an unrelated error which I assume may be the result of using a different rustup/cargo binary or something – so I'm back to RLS. Oh well. It looks like RLS and Rust-Analyzer are working on unifying their code, so I'm sure this will get better in the not-too-distant future.


Hmmmm RA has been good with me, unless I’m doing something with Arrayfire or PyTorch which are both sensitive to $PATH. RA is seriously the real deal, so I suggest wrenching around until it works. I had to modify my $PATH in VSCode to fix the issue - do you know what library you’re using that causes the issue?


Ah, thanks for the nudge. Looks like I had run into https://github.com/rust-analyzer/rust-analyzer/issues/6835, had to bump the patch version of a library to fix.


Ironically, I recently received an ADHD diagnosis…


Everyone and their mother is receiving an ADHD diagnosis nowadays. Call me a conspiracist, but I believe this is just one more case of deliberate overfitting by Big Pharma, coupled with the consequences of technology on our attention spans and other characteristics of our cognition and behavior.

As someone that might be similarly diagnosed for the same reasons, your comment does make me more optimistic of achieving something significant in my life, though.


Believe whatever you want, I am just glad that some things are starting to get better for me. I didn't need big pharma to tell me that stuff was bad, I struggled to even get help for far too long, and stigma around over-diagnosis certainly prolonged my problems here.


I'm sorry if I sounded like I was trying to invalidate your diagnosis. I'm sure ADHD is a real issue many people face their entire lives without receiving proper information or care and of course it's better to find out as early as possible. I realize now your comment wasn't the proper place for me to rant about this. I'm happy for you.


It's all good. It's a really, really tricky topic, for sure.


> you really can't make progress without the compiler's exacting approval, and I'd constantly get distracted while waiting

You can use cargo check for that, which is fast. It's only for running tests or the like that an actual build is required. Rust also has IDE integration via rust-analyzer, so the error-marking "squiggles" can be recomputed incrementally.



This is also covered in a chapter in the book when you deploy the project. I did not do a live deploy but the it looked like a nice setup even for a pet project.


It would be interesting to know where the difficulty was in training juniors to write comparatively simple code in Rust. Was it all about fighting the borrowck, or was there more to it?


> if your juniors are not self learning

At least one team member was a recent MIT course 6 graduate who was able to pick up other new technologies quite quickly without any oversight or assistance. They could get things done in Rust, too, but after a few months felt far from confident.


Is it cool now to just link to landing pages where you sell things now?

Am I missing something?

Why the hell are people upvoting a “buy now with discount code” page?


I upvoted it because:

1. HN, in my experience, is an extension of ycombinator. Since it's this guy's entrepreneurial thing, I think that's relevant.

2. I'm interested in Rust, though I've never used it.

3. I'm the target demographic for this.

edit: formatting


> I'm interested in Rust, though I've never used it.

Yep, that's how most people seem to feel about it before they try it.


Hopefully we can have some conversation about the ecosystem and state of rust for backend webapps.


You can link to any kind of meaningful content to do with rust and do that.

This is using HN as an ad platform.


HN pretty much originally existed as way to advertise ycombinator. Entrepreneurs make up a huge HN demographic. Marketing, sales, and advertising is a regular topic. “Show HN” is a special tag for certain kinds of marketing to HN users. Doesn’t seem out of place to me, to be honest.


If you visit https://www.lpalmieri.com/ you can read the chapters before buying and supporting the author.


Seems like hackernews will upvote anything Rust. I have to say, I've never tried the language, but I'm completely sold.


Because Rust?


What discount code?


I think it depends on your country. I got a 20% discount, which appears to offset the VAT I have to pay.

> You'll be charged US$62.01, including US$12.40 for VAT in <my country>.


I have been writing rust for personal projects for years. I love how the book structures the project and it is test driven. I will be using it as an example when I do projects moving forward. I like that it is one complete project a lot as well.

It is off topic for the book but I want to add a yew.rs frontend. I call it the PAY stack (Postgres actix and yew).


I bought this book a couple of months ago - I think it’s well put together and practical as someone familiar with backend development (.NET) looking to learn how to do it in Rust. Yes there’s free resources to learn anything, but most online tutorials are not in-depth. It’s up to you if prefer to piece together your knowledge from various sources or if you want to take a deep dive. There is no single right way to do it.


For what it's worth, I've been pleasantly surprised at the amount of free and open-source material supporting Rust development. There are several books covering Rust web apps (including this one) but frankly I never felt limited by the freely available materials.


I'm pretty interested in learning rust to build APIs, but I'm already productive with Java and Node/Typescript and wonder if it would be worth it, aside from being interesting.

Anyone up for giving me an elevator pitch that it would be? Or, also interested in confirmation that it wouldn't!


Rust requires more of an initial investment than Node/Java, but IMO the ROI is higher or at least more consistent. Others have noted “correctness” as a reason for using Rust, this is accurate. A few reasons I’d give for why it’s easier end more ergonomic to write correct programs in Rust are:

* exhaustive pattern matching

* Result and Option types

* builtin first class unit testing ability

* builtin first class documentation ability

The enforced exhaustive pattern matching tells you “hey you didn’t cover all cases.” Result and Option types make error handling explicit and ergonomic—the notion that each function can either succeed or fail is supported at the language level (in other languages, it’s up to you to ensure you’ve covered all cases and have thought about what “success” and “failure” mean for each function.

Testing is “built right into the language,” it’s frictionless. It’s super easy to write unit tests. You don’t have to canvass and vet a ton of testing frameworks to get going.

Documentation is easy, fun, and quick to write. So, now combine all the above with the culture of detailed documentation Rust has and now you’re really thinking through your codebase—you can use writing docs to tighten up the interfaces, seamlessly transition to writing a test that enforces some invariant, leverage “compiler driven development” to rinse and repeat this process.

The strongest reason to use Rust is that you’ve detailed the requirements for a piece of code and determine Rust is a better fit than LangX. A weaker, but still valuable reason to use Rust is to experience the discipline and idioms Rust enforces/enables and then take that experience back to your native language (I.e. exhaustive matching, which of used in certain ways can be a kind of “proof by cases” that your code does exactly what you expect, then you can easily inspect what you expect via tests).


Either:

1) Latency/peformance/concurrency/server costs

or

2) Extreme correctness

If neither of these things is a current or anticipated problem for you, it may not be worth it (though you could always do an exploratory project to find out!). Make no mistake: like any engineering decision, for all its advantages it does come with some costs.


I could see Rust playing a role in microservises where maybe you have a cpu bound service like dealing with logins being in Rust but my guess is it still isn't worth the extra cost to develop and maintain over just scaling that service unless you are getting Facebook/Google level over Java. Still fun to learn though!


Rust is performant and helps eliminate entire classes of bugs at compile-time, all while remaining fairly expressive. If none of that interests you, then you probably won’t gain much from learning it, unless you’re curious of course.


Learn it because you are interested. If nothing else you take back something you learn to another language. The zero2prod has a nice 38 page sample. I'm not sure how zero is for someone who has never written rust.


For me the hard part about Rust is the borrowing, lifetimes stuff and this book doesn't really seem to address these.

For me that means you won't get to Production (at least not starting from Zero) since these are concept that make Rust truely different from other language and without properly grasping those, you will run into hard to understand errors and code that won't compile.

It also seriously affects how you structure your code in general.

There are plenty resources that do properly explain these concepts but in the end you will just need to get it in your system, which is what I'm currently struggling with. The flow of code as I'm used to writing in C, C++, Python or Go simply won't work for Rust


I just read through the email newsletter sample chapter, this seems really well done so far!

I really appreciate how the author keeps a pragmatic approach, by copy-pasting code snippets found on the libraries docs and, at the same time, goes into details and explains every little line of code, without overwhelming the reader.

Just a quick (design) feedback: I personally felt like those blue boxes used for pull quotes draw a little too much attention. I wasn’t sure “how” I was supposed to read them at first: is this a “quick tip” box? is this something important I should pay extra attention to?


I'm currently looking for Rust devs that are interested in joining a side project that uses Rust for the back-end of a web app. The project involves working with Solana (a smart contract cryptocurrency coded in Rust). If interested, email me at rusted[at]fastmail[dot]com


I’d encourage anyone considering Rust development to simply dive in and use freely available resources online.

When I was first trialing Rust I didn’t feel like I was missing anything by using free resources. The Rust ecosystem is moving fast enough that a book might only be relevant for a short while anyway. You’d end up having to read the latest documentation to use updated packages anyway.

This may not be a bad way to spend a book stipend if you have to buy something, but don’t internet the existence of this book as an indication that it’s necessary to penetrate the world of Rust backend services.


I self-taught myself the core parts of Rust, but when I recently decided that I wanted to do Rust full time, books like this (including this one, in fact) easily paid for themselves in terms of time saved even for a heavily discounted value of my time.


Love that book!


Rust has its strength and weaknesses. Using Rust for network-latency bounded applications (e.g. web applications) simply means you're not using the right tool for the job.


I evaluated Rust for web development some time ago and was surprised that it was even worse than Go. I mean there are so many good tech stacks for web development. Why choose language over frameworks.


I don’t want to shit on anyone’s hard work because this does look cool and useful if the language was Python, Java, Go, C#, …

Using a systems language where it’s not required is just burning time and money.


As I said above, it may actually be the opposite. Depends on many factors, but the larger you scale, the less true what you’ve said is.


There was a time when Go was considered a “systems language” only, and very little web development was done with it. Same with Node.js V8, which initially had very little going for it. Every language starts without much of an ecosystem. If folks find Rust to be beneficial, we’ll see that change for Rust too.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: