In fact, NO LANGUAGE is a great choice for startups! You don't choose languages depending on whether you're a startup! You choose languages based of the problem you're trying to solve, how fit the language is for solving that particular problem, the ecosystem supporting that language, and the availability of developers who are experienced with that language.
Rust just may be the best choice for your startup, but it's not necessarily the best choice for all startups - in fact it's probably not the best choice for most startups! That doesn't mean there's anything wrong with Rust, it just means Rust isn't the right tool for the job most startups are trying to tackle. If it is the right tool then absolutely you should use it!
I've seen this in action: A startup I did consulting work for had a "genius" who convinced management that everything should be written in Haskell. As a consequence building a team was painfully slow, so slow that some guy in a weekend recreated in node.js what their 15 people team had painstaking put together in 3 months. Turns out doing a web service with tools meant for it was better than "everything should be functional".
Unpopular opinion - Haskell was intended for research and learning, not so much for mainstream production code. I'm not saying you can't use Haskell for that purpose, but you should think long and hard before doing so. If the answer is still yes then go back and make sure you've thought long enough and hard enough! :)
The problem is that there just aren't that many people who choose to invest in learning Haskell -- or for that matter, the essential-to-master nooks and crannies of Rust. And the learning curve to get there is intrinsically steeper that for, well, all those "dum-dum" ducktyped and/or mostly procedural languages one imagines you don't particular care much for, now do you.
Of course it's known that some shops, like Jane Street, have gone whole hog on FP and have managed to do all right, it seems (even arguing that "the fact that the learning curve for our bread and butter is significantly higher than for the usual college-taught languages is a feature, not a bug").
That may work if have the same brand recognition (not to mention salary and bonus pool available) as Jane Street. And even then, it's not exactly proven that large-scale FP worked out so well for them. Just that they didn't tank.
But if you don't have their clout and resoures... from first principles, you should probably think twice before making the same bet that they did.
> now do you
Depends. I like JS ok. I really like Lisps. I miss doing Ruby sometimes. I've been doing more Python lately and find it rather distasteful, all this tooling is just so so complicated for very dubious guarantees/benefit. Not all of us are a sum of tropes.
The main thing that I find frustrating is that the actual act of programming in an impure language is so much harder. Haskell is def harder to learn, like 10x at least imo. Especially for a mainstream dev. But, once you know it, there is a simplicity to what you're doing which is very easy to do. I find myself having to just think so hard when writing python. "what exacty does this function do? Oh it calls this other function, I have to go check that one." etc. And then with a myriad of control flow issues, and random syntactic "sugar" to contend with...
There are a number of haskell companies, not just Jane street, and they do pretty well. If you don't follow the space closely, it is not surprising that you don't know about it. But there are. Not nearly as many as Python or whatever, but the appeal to the popular is def problematic: mostly because, at one point python itself was a radical new thing, full of skeptics like "if its so great, why don't more people use it".
Many ideas from haskell/typed fp are slowly making their way out into the larger community. Witness Swift, Kotlin, Java, numerous features in C#, etc. People like them.
Its fine if you don't like Haskell and don't want to use it. But its not an insane choice.
Haskell community really needs to do better at making it easier to get started though. Eventually I hope to contribute to that.
You remind me that it's not the language that people use per se, it's the frameworks. Python has been around for 30 years. It was NumPy and SciPy that propelled it to the phenomenon we know today. Likewise with Ruby. I remember when Ruby was released in the mid 90's and wondering why would anyone use this language? Ten years later the Rails framework appeared and suddenly Ruby was a language that went mainstream.
Honest question - does Haskell have such a compelling framework driving its adoption? Or does Haskell suffer the "curse of Lisp" and people just create whatever they need when they need it and no big framework ever gets developed that drives adoption?
Sadly no. There are contenders for this that have arisen over the years, but we don’t have a RoR for Haskell yet.
If you’re curious, here is a talk that goes into this problem. It’s very accessible IMO. https://youtu.be/fNpsgTIpODA
To be honest, the compelling reason to learn Haskell for me was so I could engage with various academic literature. I just kept running into things I didn’t understand which were tangential to the topic of the paper, and it seemed like the most straightforward way to solve this was to start with learning Haskell. Once I learned it, I realized I was wrong in my biases, and Haskell is a fantastic tool for normal programming, with some important caveats.
But then it actually does get back to the language because the reason people build NumPy and SciPy (and Django and tons of stuff in other domains) is that Python is, after all (despite its warts) so damn easy to use. Making it easier to build all that stuff, and more rewarding also (because there's an audience).
Which is not an extra but in fact means a heck of a lot for a language's chance at long-term acceptance.
How do you know it didn’t work out very well for them and they keep it quiet just so the competion doesn’t gain the same advantage? There is that possibility or it could be that the same team would be capable enough to change the stack and paradigm and get more or less the same results, with some twist and a different flavor. It’s hard to know for sure I think.
We don't know of course; nor do we have any reason to believe it does work.
But as for "keeping quiet" -- that they aren't doing at all. They are (or at least were, when I last paid attention to this stuff) extremely forward about their belief in FP as part of their secret sauce for staying ahead of the competition.
Which, ironically, makes one further question whether it has all that much benefit. Because if it really did ... yeah, they'd probably want to keep quiet about it. Like any other truly winning strategy in their arsenal.
Yep. But sadly Haskell does give you more rope to hang yourself with. Refactoring and normal development is so easy and then people use all that power to go nuts. Such a shame.
Haskell culture is all about exploration, which means you do not know what you are doing, by definition. A large part of that exploration revolves around abstraction.
You shouldn't make the job harder than it needs to be. The main danger is using tools/techniques you don't know well. Learn radical new approaches on your own time. Don't bet the farm on the latest free monad framework which has 10 downloads on hackage.
I'd really love to hear more details about those Haskell services.
I'd put money on either the team not knowing Haskell when they started, or the "genius" was one of those completely impractical people who do type-level astronautics in Haskell.
> Rust just may be the best choice for your startup, but it's not necessarily the best choice for all startups - in fact it's probably not the best choice for most startups!
Maybe it's just an assumption on your end. Neither title nor author imply that it's THE choice. The title literally says "a great choice"
> In the next post we’ll go into some of the downsides of using Rust.
Looking forward to see how Rust is a great choice for startups doing mobile apps, native GUIs for desktop or embedded devices, or game development for consoles.
I started my first Rust project a month ago after working for years in Golang and before that Python (and before that Perl, C/C++ and Turbo Pascal). I really like the whole experience but I'm not sure if I'd recommend writing all your backend code in Rust as a startup.
Rust definitely provides a pleasant experience and is very powerful. If you can stick to the standard library I think Rust is great, though the package ecosystem is still lacking in many respects and most packages seem immature and quite limited. So if you plan to build something that has sizeable external dependencies plan some time to either write that yourself or to spend a lot of time debugging and vetting external packages, many of which are maintained as side projects by single developers. Documentation often also seems to be subpar as compared to e.g. Python. I suppose that's due to the auto-generation of documentation which seems to lead to people mostly writing what I'd refer to as API documentation with very few tutorials.
So is Rust worth it for a startup? Not so sure. I recently picked up Python again to write a simple REST API, and the process is just so much faster and (for me) enjoyable because of the "ad hocness" of the language and of course the great existing tooling around it (I still have to find an ORM as powerful as SQLAlchemy in Rust or Golang). And let's be honest it's also possible to write great scalable services in Python (or Ruby, or Javascript), as many scaleups still use these technologies.
Onboarding of developers might be another issue: Yeah, everyone wants to be a Rust programmer, but for people that have little experience with systems programming the learning curve is quite steep, so you'll limit your candidate pool quite a bit and will need more time for hiring.
1. what languages does the team already know best?
2. are any languages dominant in the problem space?
for us, I've used Python over 10 years and Python is the leader in data science / analytics. Some things might be a little faster if we used Rust, but compute is cheap. Go with what you know.
Going with what you already know is fine for knocking out the cobwebs and getting into a space. But most generally certainly in my experience I've never done anything to completion I knew at the beginning.
My response to the "compute is cheap" argument is always: Discord powers millions of concurrent live-chat and real-time-voice users from literally single (huge) VMs, using Elixir and Rust. Their revenue (relatively) sucks; its a powerhouse in communication because their revenue sucks (zero barrier to entry); and because their revenue sucks, they were forced to actually think critically about the technologies they use. They can't just throw more computers at the problem; and that limitation produced a far better product than, say, Slack.
Ok, smaller scale. You look at the latest Show HN SaaS product and wonder: "Why is there no free tier?" Free tiers are a classic in SaaS; it gets customers in the door, using your product, and you can upsell to higher tiers. Its all the same backend no matter the cost; but if your infrastructure & engineering costs are high, you may not be able to afford a generous free tier.
The days of the SaaS unicorn are behind us. Also; the days of Moore's Law (server-side at least) are quickly dwindling. This idea of "just throw more compute at the problem" needs to die a painful death. This week I consulted with a startup with something like $500k in ARR, spending $80k/year in cloud infrastructure. No free tier, all enterprise contracts, the most basic CRUD app you can imagine. A hundred NodeJS containers, every security service AWS offers enabled and logging terabytes of useless shit to an S3 bucket, autoscaling their database up to 100s of gigabytes in memory because "we don't have time to optimize". Sure; you also don't have time to not to. You're banking on some large enterprise contract to come through and buy another year; which will also add a few tens of thousands of more users to the platform, so you'll tweak the scale numbers up again, and again, and just keep praying one day you can cost optimize. Every day that goes by makes that harder, so you're also praying that maybe you can find more talent to do it, maybe we can grab some people from these layoffs, except what if we don't have the money to pay for talent just like the company that laid them off?
Python, JS, Big Cloud, had their time and were valuable during it; but today, startups need to think about cost optimization from day 1, and every cycle a CPU spends doing something is a cost. I'm not prescribing technologies; I'm just asking for more critical thinking, and not always operating with the "throw money at it" mindset. Maybe python makes sense; how can we deliver it with extremely low costs? Lambda? DigitalOcean? Can we integrate a more performance-oriented view into reviews? This part of the app experiences 10x the traffic the rest does; can we break that out into something far more efficient?
I agree that one doesn't necessarily need a fast language, but I think that the "hardware is cheap" idea is very misleading. Renting/owning 5x as much servers may be cheap, but maintaining them isn't.
1 may be better asked as what aspects of your team understanding of any considered language apply to your problem space. How well can you port that knowledge to another model of expression.
2 is fine. the more significant question is often do you want to work with that talent pool and does the pool tell you more about the costs structure of your sector against which information you may prefer to tack against the prevailing winds and even more patiently attempt to trade actual equity for deep abilities and stuff what language is chosen if your stock has value.
I don't understand how much attention individual languages receive. Plural understanding across your team and ability to transcribe the code into valid parseable docs against which APIs are easily written, is paramount in my mind. Corollary to my incredulity I have often thought that you emphasize the codebase language and dialects only to find you fuelled holy wars and dissipated your technical mission values. Which is disastrous for hiring the kind of colleagues we get up in the morning and forget about industry grief to share increasingly awful spaces with.
> I recently picked up Python again to write a simple REST API, and the process is just so much faster
For me it's much more important how will it work in the next few years, not how quickly you can write it. If I could, I would use Rust for pretty much everything just because I don't like getting paged in the middle of the night.
I have both Python and Golang web services in production for years, none of them cause much headache. I'm not running a hyperscale startup though and server hosting is the smallest cost factor for running my products, so I don't worry about performance that much. Most workloads are IO-bound (database queries) in any case, so Python isn't too much at a disadvantage over Golang or Rust there. In terms of stability I never had any major issue with Python services, and when minor issues occured the logging and tracebacks were so good that it was easy to isolate and fix the problem (the same is also true for Golang).
I guess the older you become the less you care about specific tools or languages, for me it's mostly the general architecture and operating principles of the software that determines if a system will be brittle or not.
I agree. This typing velocity argument is really weak. It may be faster to start, but talk to me once the project reaches 10K+ lines of code and we'll see how you fare with your scripting language.
I don't remember the 'satisfying the borrow checker' phase lasting more than a few weeks. Once you internalize the rules the borrow checker gets out of your way and it's more of a sanity check.
I think part of the issue is that it wasn't very well explained in the book at the time I started learning rust. This might have improved since.
The entire way of coding in Rust revolves around satisfying the borrow checker. At some point it may become second nature, but you are still jumping through Rust's hoops, which will make your code full of compromises that would otherwise not exist.
>you are still jumping through Rust's hoops, which will make your code full of compromises that would otherwise not exist.
The same can be said in reverse. There are many, many C and C++ codebases that make design compromises and copy data unnecessarily so as not to be utterly hellish to maintain. People meme about "fearless concurrency" but it's true, with Rust you don't need KGB levels of paranoia and attentiveness to write parallel or reference-heavy code. I can write code in Rust I would never be comfortable writing in C/C++ because the language gives me the confidence to not compromise in those areas.
So does the entire way of coding in any static-typed language, your code is full of compromises that would otherwise not exist in a dynamic-type language. Rust is just another layer of static typing.
"It really puzzles me why smart people want to spend their time satisfying the (compiler errors | warnings | linter) rather than inventing new and useful things."
Over the past fifty years we've realized that even incredibly smart people suck at avoiding the gazillion pitfalls involved in programming. Virtually every professional programming environment these days employs a suite of tools that help ensure we don't make certain classes of avoidable mistakes, and the borrow checker is simply another one of these tools to protect us from ourselves.
Am I to assume you don't turn on any warnings or linters in any of your projects?
I wouldn't touch Python with 10-foot pole for any serious project. People who're used to dynamic languages (e.g., JavaScript) are now starting to see how indispensable static typing is when they try out TypeScript and then never want to go back.
I also write Python with type annotations and the type checker keeps getting better and better, though I find it's often not strictly necessary, at least for small projects. The most important thing is to keep the code simple to understand and follow, then you can write great software in dynamically typed languages as well.
Also have Typescript experience but in general I'm not a big fan of gradually typed programming languages, static typing works best in languages that were designed for it from the ground up and that offer an expressive type system, e.g. C++ or Rust.
I would not choose Deno for that considering how little there is for it currently and how much of what there is available that is plastered with all caps warnings to not use it in production.
I've been using async Rust in production for years. The learning curve is a little higher than I'd like. But it works great and it does everything we need it to. For an open source example, see https://www.dbcrossbar.org/
Many problems with async Rust involve people trying to get overly clever with lifetimes and zero-copy code. And if it's not either of those, it's people getting overly clever with async traits. So keep it simple!
Some tips:
1. Long-running async tasks should own their data, not borrow it. This will save you 80% of the pain right there.
2. Don't be afraid to allocate futures on the heap, and use "Box<dyn Future<Output=T>>" to hide the implementation.
3. If you must use traits with async members, use "async_trait".
4. Remember that futures can be cancelled at any "await" point. You can ignore this 99% of the time, as long as you use destructors to perform cleanup.
I would only recommend async Rust if you actually need very high-performance async code. Regular threaded Rust still works great for most things, as do languages like TypeScript. But if you actually need what async Rust offers, it's totally workable.
This constant refrain must be discouraging to the people who have worked so hard on async rust. Can we please restrict our criticism to specific problems, and temper it with gratitude for the amazing things that the Rust developers have already given us free of charge?
I am not sure what is so "un-tempered" in the original message (assuming it is not technically incorrect) and what makes Rust so special that criticism must be "tempered with gratitude".
It's too vague. The claim is that async "still doesn't really work" but like, how so?
Sometimes you could make a claim like that about a feature and it's more or less accurate just as it stands. C++ 20 Modules were like that (still might be like that?) on most platforms, 'cos it turns out that's a lot of work for a compiler to implement and it's important to say you have the feature even if you know it doesn't work well. But even then, I'd rather see e.g. "C++ 20 Modules blow up if I try to A, or B, or C... or Z" it's just that I can understand if your list is a page long "doesn't really work" seems more concise than listing everything.
There are clearly people who are frustrated by aspects of Rust's async. Some of those frustrations are fixable, some are consequences of a principle decision that's unlikely to be revisited, and who knows if you won't say what frustrated you
Suppose I said Go's generics "don't really work". Do I mean that they aren't monomorphised in the way I hoped? That the syntax is too untidy for me? That the Go libraries aren't yet making them ergonomic? That I found a compiler bug? No way to know.
Well, I have several production services. They are written in async rust. If they didn't work, or worked poorly, or even worked sorta good - you'd know it, the outages would be front page news in the tech press and maybe even on "the news".
I didn't have to do anything special to make them work well, just out of the box tokio and a small bit of learning how to do stuff that's weird to do in most any language (e.g. netlink, bpf maps and so on).
I don't know what the definition of "doesn't really work" is, but it seems technically incorrect given how my services run for months at a time between restarts (which I consider a symptom of working).
Rust isn't special; what I said applies to any open-source project. But people have been pretty harsh about async in Rust lately, and IMO the message I was replying to makes the problem sound worse than it is.
My main issue with Rust async was that it wasn't possible to write a "runtime agnostic" libraries. For example, I wrote an HTTP client with Tokio and later wanted to use it in a project that was using another runtime (I think it was async-std) and couldn't use it. I wonder if that has changed since then?
That's basically only a problem if you use async-std (just don't, and switch your project if you have). Pretty much everything supports tokio (or there is a just-as-good equivalent library that supports tokio).
Which isn't to say this shouldn't be fixed. Just that there's a fairly good away to avoid the problem in practice.
This is probably more of a concern for people who aren't writing services/ professional devs. Otherwise, who cares, you pick a runtime (tokio) and you use it - runtime agnosticism isn't a real goal for any company.
I don't really need to find those examples, I've written most of my company's product in Rust using async, for years, and it's never once been an issue. That's 100s of thousands of lines of rust written and 0 async issues.
Totally valid, but you could also say the same thing about C and C++, i.e. you can wield your tool with mastery, then that's awesome. But I think the average startup would likely struggle needlessly when they really just need to ship products that people want/need to use. Rust is likely not the smartest choice for the average startup.
Only one person at the company had previous professional experience with Rust. The majority had 0 experience with it at all. We've had no trouble and it's actually been our most productive language - we're moving away from Python and Typescript where possible.
Startups are about cost, time to market, and a high level of efficiency to deliver on a promises ( product ) to sell or get to market. A language selection should consider two things, talent pool and maturity of the tools.
When you go hire developers, I want a strong pool to be able to be selective in finding attitude with the right aptitude, and I want them to be productive ASAP, so that means that we might bring in GNU protects that we are extending, tooling from other sources and high level knowledge of the code… this is where maturity comes in, not the language that matters, it’s the package you get on the product you are developing.
I love rust, it will get there, but in a startup environment, it could end up been “not the best fit” all things considered.
Exactly, I did startup before, and my take is: Rust is absolutely the worst choice for startups.
to survive startup, you need a large pool of talents, mature and verified and boring stack, easy to find tutorials, etc. The least thing you want is to spend cycles on fancy new bleeding unstable languages to build your earth shaking product.
Forgive me if I'm quoting you out of context but the article mentions receiving 4000 applicants over 8 weeks time. I've hired (primarily) for Java and DBA positions, and we would be absolutely thrilled if we got even 40 applicants.
"Many didn’t actually have Rust experience at all and that’s fine, they were just interested in the idea" -- to me, that's _not_ fine. startup needs to move fast to stay above the water, it's not the best place to learn 'coding in Rust 101' IMHO
Where does a language magically go from "new bleeding unstable" to something you think is suitable to use at a startup ? Rust 1.0 was in 2015, seven years ago.
Do you think a startup should also avoid the "fancy new" ES6 with "let" and arrow functions ?
When I see people complaining about "experimental", "new bleedy unstable" I always picture some weak developer complaining about the language not being Java 1.4 and having to learn other stuff that is different from enterprise OO invented after the year 2000. See Rust (7 years already), Haskell (older than Java), React (9 years).
They all miss their 5 million LoC mudball at the bank, because that's all they know how to do.
I'm doing some work on a friend's startup, and we have a pretty stark divide between our hot path gateway service and our lower traffic services.
All three of our services are currently written in typescript with no plans to change, but I've earmarked the gateway as "maybe we'll rewrite it in Rust in three years." It's so small it's nearly trivial (so a rewrite of that specific service will be quickish) and infrequently changed (so hiring won't be as big an issue), it deals with low latency IO-heavy workloads (so we'll possibly want a language without GC pauses), and we really don't want it to break (so it's worth more effort per line).
FYI: If you're primarily IO-heavy, the GC pauses aren't going to be a big deal. Something like NodeJS (or Async .Net) will have great performance; even with garbage collection. (IO-heavy is the specific use case that NodeJS was designed to handle.)
GC pauses really become a problem when you have long-lived objects in RAM. A generational GC (which pretty much all of them are) is designed to collect short-lived objects extremely fast.
Rust definitely has its use; but in the case of a startup making an IO-heavy product, you're going to be better off spending your precious resources on a slightly faster computer instead of struggling with Rust's learning curve.
> FYI: If you're primarily IO-heavy, the GC pauses aren't going to be a big deal. Something like NodeJS (or Async .Net) will have great performance; even with garbage collection. (IO-heavy is the specific use case that NodeJS was designed to handle.)
This just isn't true. Node is pretty terrible even at IO heavy workloads, especially if you have servers with many cores. Any benchmark will confirm this.
> FYI: If you're primarily IO-heavy, the GC pauses aren't going to be a big deal.
To further my point: .NET and Java are amazing when it comes to performance for most cases. You get a mature ecosystem, large developer pool, fast runtime and all the comfort that GC offers.
I'd argue that choosing Rust for most startups is outright irresponsible.
This is sort of highlighted by other comments, but GC is only good at small quick requests. If you're dealing with large or slow requests it results in large or long lived allocations which causes havoc with GC. This is true for any generational GC, Java included.
Also node will only perform well if that IO is offloaded to the kernel or CPP code and behind a future via epoll etc... If it's in the actual node runtime it'll perform poorly because it'll block the thread.
I don't necessarily agree. Depending on what kind of IO they're doing, the latency and consistency of latency from a rust service can be so much better while requiring so much less in terms of computing resources that it actually sets their business apart, attracting customers based on quality or saving them enough money on infra bills to hire more salespeople. It can be a big difference in performance. I have done comparisons across rust, node, java, c# and strongly believe rust is worth it for performance-criticial code, and rust is subjectively very enjoyable to write, for me. I really want a job doing it and so admittedly the "it's too hard" attitude is a thorn in my side.
Are there any good books that talk about this? When when to use what, what the bottlenecks are and how they are resolved? Maybe on a more abstract plane than if IO-heavy use NodeJS, more like what to look for?
The hybrid approach works great. We use typed scripting languages for business logic and Rust CLI tools for "inner loops", and this balance gives us the best of both worlds.
There is an important caveat here: If you are already comfortable in Rust, then it's a fantastic tool for all sorts of things. But if you're just learning Rust, then there's a one-time cost for getting comfortable. So for a small team with zero prior Rust experience, expect to spend 2-6 weeks getting comfortable. (The learning curve is shorter if you already know about pointers and closures, and longer if it's your first low-level language.)
The 2-6 weeks figure seems optimistic to me. I think it’s easy to underestimate how long it takes to switch languages and operate at a high level of productivity in the new language. Yes, switching languages is much easier than learning to program. Yes, I would rather hire a proficient programmer who doesn’t know the language than a mediocre programmer who does. But no, I don’t think that 6 weeks is enough for most people to get their Rust skills to a professional level.
> The learning curve is shorter if you already know about pointers and closures
Every time I read something like this, I'm reminded that pointers and closures aren't universally understood concepts in professional programmers. And I'm sad.
I share this sentiment, it's kind of a bummer. I ran into this non-stop in enterprise Java/C# development environments, more specifically in developers who are not "classically schooled" (i.e. bootcampers).
Fact of the matter was, they never needed to know about pointers to do their job. They only even knew the term from the "null pointer exception". I looked into the curriculum of various levels of IT studies and unless you get taught at university level there are little to no memory / hardware oriented classes.
It has started to get a bit better since the introduction of Java 8 (don't look up how long ago this was, ouch) and people got familiar with "lambda's".
On the other hand, you might attract talent that wants to use a specific language like Rust, but hasn't had the chance in their current professional environment.
It's also worth considering what will keep the founder(s) motivated to stay focused and do good work. Yes, using JavaScript and Electron might be the optimal rational business decision, and in theory we should be motivated solely by the problem we're trying to solve. But if the technical cofounder, who's currently the only programmer, then feels that they're creating something that nobody can really love, and they get discouraged at the state of the world that led to that decision in the first place, that's not good for productivity. You can probably guess how I know this.
> what will keep the founder(s) motivated to stay focused and do good work.
I would not want to work with a cofounder who loses focuses when they don't get to use the trendy technology. They should be focused on delivering value.
That'd be a disaster for a startup. In order to use Rust efficiently, one needs to have a significant experience with it; without experience, one wastes a lot of time wrestling with ownership, lifetimes etc.
(I do program in Rust in my (non-trivial) hobby projects).
I've been toying with Rust on and off for a few years. It has an extremely steep learning curve. As a novice it's incredibly difficult to do things that are trivial in other languages.
> On the other hand, you might attract talent that wants to use a specific language like Rust, but hasn't had the chance in their current professional environment
Maybe if you're doing something embedded? Otherwise, the learning curve is so steep that you're better off just buying a faster computer to run C#/Java/NodeJS/Python/Whatever.
We've had 0 issues hiring for Rust, despite the vast majority of the company having no prior experience with it (or some experience on the side). The learning curve isn't that bad, maybe you just haven't dedicated the right time or you've had trouble learning it in isolation.
Actually, I think Rust is a godsend to startups for the following reasons: 1.) startups rarely have time, expertise or budget for extensive unit tests, mock-up tests, UI-automation tests or paid third-party Q/A services, 2.) software product users these days have a strong tendency never to submit bug reports or work with product support, but instead just leave negative reviews and/or just move on to the competition, 3.) when an MVP actually does get a chance to grow in size and complexity, startups hit the growing pains of efficient problem report accumulation, recognition (troubleshooting, often with a non-technical third-party), prioritization and resolution.
Every programmer who has ever maintained a product of 100,000+ lines-of-code will tell you the same thing: shift as much responsibility as possible on the compiler (and the API consumption boundaries). Fixing code due to a bug with memory management, unexpected mutation, multi-threading, etc. will cost you 10 times the effort required to write that code in the first place.
Ocaml is absolutely playing in similar spaces as rust. I see the tradeoff there as one of runtime performance (Rust) against less syntax / dev effort (Ocaml). If you don't need your code to go fast, Ocaml is probably just fine for you to use. Hell, Jane Street famously does so and has talked in great detail on their podcast and in articles about the many strengths and tradeoffs involved here.
Given how many startups work with python, which is notoriously slow, this is a somewhat ridiculous statement. Ocaml's performance is probably 50ish% of Rust's at worst, which I claim is more than enough for 99% of the problems out there.
Rust's popularity, again I claim, has almost nothing to with its performance. It's more about the much more modern tooling, relatively simplified language (for most parts, though obviously not all) and superior marketing.
It's more like "if you need your code to go extremely fast" though, which is honestly pretty rare in my experience. Ocaml is no slouch and people regularly build great products on much slower languages and that's rarely the limiting factor.
I don't know OCaml, so I cannot compare the two, but, generally speaking, Rust does not require functional programming, or using only immutable data structures, or using cloning, or using copy-on-write semantics (which have to properly handle the reference-type-inside-a-value-type problem), but works through no-copy data ownership transfer, multiple immutable references, or only a single mutable reference to data at a time, all checked across threads at compile-time. Finally, Rust is not garbage-collected, so it can be used in resource-critical environments, such as embedded, metered serverless, Linux kernel drivers, etc. If you're interested, have a look at the "A Firehose of Rust, for busy people who know some C++"[1] video.
Ocaml to this day has issues on Windows. Its a phenomenal tool, but adoption is always going to be hampered while the world's dominant desktop OS is a second class citizen for that tool.
No, not really. Rust undoubtedly started on *nix, but all Tier 1 platforms are supported equally[1]. To quote from OCaml's main site[2] A gentle reminder that if you do not need Windows binaries, then a more stable option is to use WSL2, ie when on Windows it is better to use OCaml from within a Linux VM.
Ocaml is great, but its Windows support sucks, and that makes adoption hard in a lot of contexts.
Any language that calls themselves systems programming language, on Windows, must have first class support for COM and WinRT, in their various workloads.
Rust support for them is pretty much WIP.
And then there is the whole matter that Windows shops love to ship binary libraries.
What languages/platforms do meet this criterion? .NET, C, C++, Python? I know pretty much nothing about Windows system programming, but I wouldn't be surprised if most programming languages really are "Unix first".
Ocaml wouldn't be a bad choice if it were livelier. Few learning resources, and perceived smaller ecosystem create a vicious cycle that hamper its adoption.
>(...) despite my experience and best intentions, I was in fact making mistakes with C. Subtle leaks, use-after-free,(...) Rust made it very clear that I was not the programmer I thought I was.
This really resonated with me. I feel a lot more confident writing code in Rust than say in C or Java. However, in my opinion, it also comes with a downside: These days, whenever I use a 'more forgiving' programming language I find myself being much more paranoid of the code that I write. Even after double checking everything I still miss the memory guarantees that Rust brings, and end up spending a lot of time making sure things are behaving the way they should.
I still find this type of comment odd (although I do also recognise that it's very common).
I write a lot of code in C++. And I'm definitely no fan of it, so I'm not here to defend it! And I write a lot of bugs in that code. But very few of them are segfaults. With smart pointers and some common sense, they're just not that big of a concern. Yes, they do happen, but it's far a minority of the bugs. Maybe everyone just has better tests than me? (shrug)
I like the look of Rust, though I haven't yet got to use it professionally. I actually think it would be a perfectly good language without all the lifetime stuff, with lots of improvements over C++ (destructive move for a start). It would probably be good enough for most purposes, and the improved uptake would result in fewer bugs overall than the current situation.
It's academic really since that's obviously not where we are. But, like I say, I don't think memory errors are that problematic in C++ in practice (unless you're writing security sensitive code where even an occasional one can cause big problems).
> But very few of them are segfaults. With smart pointers and some common sense, they're just not that big of a concern.
I think it's really a POV thing. Rust surfaces those concerns very directly, even if it would have been correct 99.999999% of the time, Rust will enforce another decile of correctness. Since it does this quite aggressively Rust's users tend to have their mind (mine included) a bit (over)fixated on those issues.
(also, in Rust you don't use common sense, you use the compiler, and imo that's great, my common sense has failed me enough)
Rust's "lifetime stuff" really is overemphasized. You can write years of totally ok Rust code without ever having to handle a single explicit lifetime. They're there, and one should have a general picture of how they work, but unless you're doing high perf / library stuff, they can generally be sidestepped.
I believe there should be a Rust manual that shows the easy way in, using Rc/RefCell before reaching for plain references. So many people get the idea that if you're not using the hardcore smallest construct to extract that very littlest bit of performance, you're "doing Rust wrong". The overall idea of Rust is that of safe code and although the compiler and language semantics obviously play a major part in it, the standard lib is actually very nice too and helps a lot to get away from the harsh realities of bare system programming.
You're benefiting from elision. Modern Rust lets you omit mention of a lifetime when there's only one plausible choice. So, often today you can write Rust that doesn't mention lifetimes but they're implied.
But it wasn't always like that. For a while Rust would insist you spell out that OK, this function parameter has some lifetime 't and the function result also has a lifetime 't. Now, Rust says well, the result needs a lifetime, and your function takes one parameter which also has a lifetime you didn't specify, so, the plausible explanation is that they're just the same lifetime, let's assume that's what you wanted and only complain if that won't compile.
> I actually think it would be a perfectly good language without all the lifetime stuff, with lots of improvements over C++ (destructive move for a start).
I'm not sure what you mean by this exactly. Do you mean Rust would be a perfectly good language without its safety guarantees? Because it can't have them without lifetimes. It could instead have GC like Go/Java/etc, but now it's a GC language.
Lifetimes aren't a feature of the language. They are the implementation details for a couple features of the language. It's how it gets there. And I don't think Rust would have anywhere near the interest it has without those features.
* As other comments have mentioned, security bugs matter more in some products than others. (E.g. think of a desktop application connecting to an organisation's own database.)
* That includes a whole lot of code (maybe the majority) which is either C or C++ from before C++11, given that the bugs were tracked in the period 2006 - 2018. Never mind a hypothetical Rust-without-lifetimes.
70% of all security issues is not 70% of all bugs. For the large majority of software products, security issues are an infinitesimal minority of bugs, and arguably, for a significant chunk of software products, security issues are not even critical.
I should have said: for a significant chunk of software products, there cannot even be security issues at all. If you disagree, just look around, preferably outside a "network service" mindset.
That's 70% of CVEs, not 70% of all bugs, which is a massive difference. Most programmers don't deal with CVE worthy bugs on a daily basis, no matter what programming language they use.
It's fact that it's easiest to cause a CVE bug in a language that you manually manage memory. So it's true that most likely JavaScript programmers may not cause them too often ;)
Anectodal, but: I had been working on a mixed C/C++ code base which grew over around 20 years to about 1mloc, with a team of programmers varying between 5 and 20, and we had to deal with memory corruption issues around once or twice a year, and those could be solved relatively quickly (even more quickly with modern memory debugging tools like the memory debugger/profiler in Visual Studio).
At the same time, the bug database for the project had a "throughput" of about 5..10 bugs per day (for the programming team, many more for the entire team). The amount of memory related bugs relative to "regular" bugs is infinitesimal even in a C/C++ code base.
Of course I realize that the code base had "sleeper bugs" that hadn't showed up yet, and a memory safe language would have helped to prevent those. But I just wanted to point out that memory corruption issues are just not a daily topic in most C/C++ projects.
In the end, safety comes down to the sandbox your code runs in (for instance operating system processes, or Javascript VMs). Should those sandboxes be written in Rust? Most likely yes. Should everything else be written in Rust? Nah...
For this to work, you'd need most of the code to be written by people who are paid (i.e. professionals).
In my experience somewhere between 50-80% of code at most places is stuff pulled off maven/npm/github/etc written by people who are completely uncompensated, and possibly as hobby projects.
You could censure devs pulling in unverified code, but so far as I can tell, the vast majority of devs are really bad at reading code. I'm doubtful it would change anything.
This seems like something that should maybe covered in a computer science curriculum, but most colleges seem to have an aversion to becoming "job training" centers. If they don't start teaching it, I'm not sure how you can expect people to have training in it. Do we need a training course outside the traditional university system?
The problem with this idea has been the same for 40 years: unlike in other fields of engineering in Software there is no bedrock of empirical science from which we can derive objective, reasonable standards. It is all opinion in CS and no doubt the most obnoxious, useless methodologists would be the ones with the strongest opinions about how others should build things.
I would love a world where that would happen; and also get years of testing, proof of concept time and funding to make all that actually happen. Not counting on it thoug since cost would skyrocket.
Both you and parent are correct. Memory safety issues in c++ code are common, but very often they don't manifest as segfaults. Malloc assertion failures or occasional data corruption in edge cases or "impossible" behavior are more typical symptoms.
Memory issues are rare in every C++ project I’ve ever worked on when compared to much more common bugs in expected functionality (the biggest category), bugs introduced by new or updated libraries, or operating system deprecations, etc.
Overall, the aversion to C++ and other non-GC languages is overly stated in the industry by vendors looking desperate for a problem to solve to validate using their new language or as a solution for companies that want to hire large armies of sub-par developers to bang on keyboards.
This kinda counter-resonates with me. I'm not a superb programmer by any means, but C's memory management rarely caused me bad problems. I find it much easier to deal with than the complexity of languages like C++ and Rust.
Calling malloc isn't even manual memory management to me, it's just calling malloc. Writing malloc (not that hard in general! but tricky to get exactly the allocator performance or security properties you want for your use case) is manual memory management.
> In computer science, manual memory management refers to the usage of manual instructions by the programmer to identify and deallocate unused objects, or garbage.
So, you can call it however you like, but calling `malloc()`/`free()` manually (emphasis on the `free()`, since allocation is explicit in most languages in form of `new` or something) is manual memory management, and this is how most programmers use this term.
I understand the comparison with C (the memory management) but I wonder how do you compare Rust to Java? What is it that makes you feel more confident in Rust compared to Java?
Java _used_ to give me that "it just works" feeling when I started using it... in 1999. The rich type system makes the biggest difference. In Rust, you can solve a problem by first modelling it through structs and enums and then define operations pertaining to elements of the model. rustc (the compiler) has such a grasp on the implications of a given model that it will most often guide you toward a near-optimal (and safe) solution that ends up working flawlessly the first time you get it running.
Rust has a cool type system, but I think you give it much more credit, like it doesn’t have dependent types where the implementation can often be filled in literally.
Other than checking mutability and nullness, I really don’t think that Rust would be that much ahead compared to even an “older” language like Java.
Also, java now has ADTs so “exhaustive checks” are available there as well.
I can't compare with Java, but I can for C#. With Rust I find that I have much more confidence that I understand what the code is doing primarily due to the borrow checker and how Rust enforces unique vs shared access vs ownership. Just by knowing the types involved, I know exactly what a function could potentially do to what I pass in just by looking at the call site.
In C#, I can't tell at the call site whether a function could mutate what I pass in; not without looking at the implementation of the function and anything it passes that object to. With Rust, how it's passed in completely informs me about this. If it's passed by shared reference, it can't mutate. If it's passed by unique reference, it might mutate. If it's passed by ownership, then I can't access the instance any more anyway, so it's not my problem.
I think you shouldn't compare Rust to Java (the language), you should compare it to Java (the ecosystem). The JVM is rock solid and very performant, and you have languages like Java++ (called Kotlin) and Haskell# (called Scala), or even Common Scheme (called Clojure). The same is true for the ecosystem, eg. build tools (Maven/Gradle are the default ones, but there are many more), frameworks (Spring + all the reactive stuff), the largest number of libraries on the planet after C, and so on.
The target niche is not exactly the same though, you wouldn't want to systems program on the JVM, and it would probably not make much sense to choose Rust over Spring Boot for web programming. YMMV of course.
You're right that with regards to memory management, using Java over Rust doesn't make me any more nervous. The things I really miss are at the type level. Small things like the compiler forcing you to be explicit about mutability. Large things like Rust enums and pattern matching which make it easy to model complex workflows without worrying about missing any cases.
Let me also make clear that I like the direction Java is moving (even if is taking decades) For example, something I look forward to in Java is pattern matching on switch expressions, which just got added as a preview feature in the latest LTS.
The myth of segmentation faults being hard needs to die. A fault is like an exception in Java (or a panic in Rust for that matter), only generated by hardware. It's the best case scenario for your buggy code. It's when you don't get a segfault, but your buggy code keeps chugging along, that's a problem. If after using an out-of-bounds index into an array I get a segfault instead of a memory corruption, I thank god for his mercy. The alternative of the program just continuing execution is horrible.
Segfault is only best-case scenario if it happens at the location with the bug.
It is extremely common to start diagnosing a segfault and find that the location of the segfault, in code, is unrelated to the code which caused the segfault.
My experience (15+ years of debugging legacy C code) is that if the segfault is repeatable - as in you can make it happen in the same place over and over again - the fact that the error is somewhere else only makes things marginally more difficult. Even the old-fashioned debuggers can monitor memory locations for changes, and if that doesn't work you can set breakpoints in various locations and manually check memory for corruption - it can really narrow down the possibilities.
I always enjoyed the mystery. It's a puzzle with an as-yet unknown solution. How can you not love it?
Oh yes, for sure. Visual debuggers make things so much easier! It might be worth pointing out that visual debuggers have been around for well over 30 years at this point.
Sometimes you can end up in a pickle because the embedded system you’re working with just doesn’t have a good debugger available, or it may be cumbersome to set up.
Sometimes the segfault happens in a production environment and you just can’t hook up a visual debugger to the ten different instances of the server you’re running.
I agree that a segfault is a fun error to try and diagnose because it really exercises your gray matter. But it’s not my job to diagnose segfaults, it’s my job to keep the service running up to some certain standard, and if I find myself diagnosing lots of segfaults, there is usually something else I could be doing involving instrumentation or testing to address those defects which is more boring but more productive :-)
I am a professional C++ programmer and I can’t even remember the last time I had a segfault. I also haven’t had a bug in production the last 5 years. But YMMV of course.
Well, because geniuses who were too smart for their own good turned every problem into an academic exercise, writing "elegant" code using the darkest corners of the vast language that is C++. And then we hate the language and not these characters.
Scala has the same problem. Stop writing your own DSLs!
Author here: lots of usual language-war type comments here. Just thought I'd add my own little bit of water (hopefully).
In my post notice that aside from my personal background with programming I didn't go into detail about memory safety, which seems to be what many are debating. Frankly, it's not even one of my top reasons for praising the language. If I had to pick three these are what I'd choose:
1. Strong features for describing real-world issues in software. Here I'm talking about things like tagged unions (enums). They let you describe so much very cleanly. Use a match expression on it and you can be sure you've handled it pretty well. These lead into the stdlib's Result and Option types which extend what I said further.
2. Excellent performance without any fancy language stuff like annotating lifetimes. Using the Iterator trait you can chain up a really nice operation FP-style and get ridiculous performance. It takes fewer lines than idiomatic Python.
3. Excellent tooling. Cargo is easily the best package manager I've used (yet, someone show me better!). When doing async work the tracing crate is great, it automatically handles all the entry and exit points of the state machine that gets generated. You can also use tools like tokio-console on it, or export via opentelemetry.
I think it's worth making the distinction between Maven as a build tool and Maven as a package manager, because the latter I think does work quite well.
I've had enough maven for a lifetime. Too much time spent fiddling with settings.xml files and m2 folders, debugging builds in enterprise environments with dozen module projects and a mix of internal and public dependencies.
Well, it is hard to get a true picture without some probably paid data, but Scala has been around for longer (especially if we only look at the time when the language was reasonable well known), and I know plenty of companies that have significant Scala code bases even from the top of my head. Rust, not much. Of course I could be dead wrong, but I think as of now Rust has more hype than actual code written in it (but it is not baseless hype, imo the language actually lives up to it so its usage will likely grow faster than Scala’s)
Blog post is just rationalization for their choice. Rust is actually terrible choice for startups.
It will take 2x more time to develop same thing than using something like TypeScript/Python and you will have much smaller and more expensive talent pool. Startups usually have to make, at least minimum viable, product quickly and start selling it before funds dry out. That means using familiar tech with big ecosystem.
Also choice of tech is probably least important thing contributing to startup success. That knows anyone who worked in terrible codebases that were generating multi-million revenue. Customers don't care about your tech. Simple as.
I write Rust and C++ for a living and completely agree with this. While I do like Rust in general, the language is so complicated that anything other than trivial programs is going to take way longer to implement than in any other language. Testing code in Rust is also half baked at best, I find that any other popular language has better capabilities than Rust in this aspect, including C++. I'd even go as far as saying that for a startup I'd use C++ before Rust if performance was a feature, otherwise I'd just go with something that has batteries included like Python or Golang.
Depends on what you're doing. There are apps that can be written in Rust much more quickly than in other services, cause you don't have to worry about a lot of stuff (like for example it's hard to keep an open connection for every client and process everything real time in Ruby on Rails).
I recently was thinking about how smart/not-smart would it be to become a full-on 'Rust developer'. So I thought, OK, what happens if two decades from now I'm a grey-beard Rust programmer, and the only jobs I can find are maintaining some legacy Rust code...
And then it struck me, I'd be completely fine with it. As in, if there's a language in which dealing with legacy code doesn't seem daunting, then that's Rust. Because of the safety guarantees, the type system, and the 'compiler knows better', refactors are just so much easier. Like, hands down I'd rather maintain Rust code than Python, PHP, JavaScript, or C++.
In principle, yes. But bear in mind that Rust doesn't depend on a runtime, and compiles to LLVM IR, so what it depends on to run on the target system is a lot less than something like PHP, Python, or JS. So to really end up in deep shit the LLVM project would also have to fizzle together with Rust.
And given how some 'big names' in tech are getting more and more involved in Rust and opting to write core low-level stuff in it, I'm not terribly worried about Rust and LLVM fizzling to the point where I have to worry about any of that. I mean, it is orders of magnitude less of an issue than depending on Node.
I would argue that Rust is a great choice for startups exactly because you can find people who will either take a pay cut or work in a hectic environment, just so they can use Rust. Rust has been on top of everyone's "want to learn" list for half a decade, and it feels quite mature.
Definitely I would not take a pay cut for rust, also for any technology, it’s about solving problems and working on interesting things not really about a language. I’ve also been learning rust in my spare time, and am more and more realising that I spend time solving rust’s problems more than solving the problems of the side project I started
I'm surprised to see multiple people mentioning pay cuts. In the Stackoverflow Annual Developer survey[1] I see Rust developers consistently being among the highest paid in the industry.
I'm mentioning pay cuts because one of the side-effects of joining a startup is that they can be tight on money and will offer early employees shares instead.
I work for a startup and am coding Rust and my salary went up by taking this job.
So I'm only saying this as a general thing; I'm sure a lot of startups where Rust makes a difference (I'm sure a lot of startups would be just as well off with Python), they can probably afford a competitive wage. :-)
Maintenance is where Rust really shines and makes up for it's initial learning curve and slightly slower writing speed. In terms of hiring I can't imagine it being a problem either. There are lots of developers who would jump at the chance to work with Rust, and comparatively few Rust jobs (especially ones that don't involve working with cryptocurrency).
There are lots of people curious about coding Rust in production, and most of them consider themselves competent to write it. But that is not what you look for when hiring. Or, it shouldn't be.
I would say that curiosity about languages in general is one item that you should look for in candidates. Not the only one of course but curious people do tend to learn and adapt well.
For an analogy, I wouldn't hire a pilot that isn't interested in other planes than what's on their license. What if I want to operate some new models?
Unless I'm looking for someone for a truly specialised role, I would avoid people that stick to only one thing for their entire careers.
Curiosity is a decent indicator one of the many types of competence that you ought to be assessing: the ability to learn new skills and deal with problems that are outside of their current skill set. Which for most software jobs is rather key skill.
I don’t believe Rust is that good at maintainability - refactors are safe, but they are very tedious, which is inherent to its low-level nature. In a managed language if a refactor causes different lifetimes/ownership model, the runtime will automatically handle it. In Rust you will have to fight the borrow checker for it.
Don’t get me wrong, Rust is a really great language, but if the domain doesn’t require low-level programming, don’t choose a low-level lang, in my opinion.
There seem to be a lot of long running Rust job openings in the cryptocurrency space. Maybe those positions are always open because nobody wants to work there? You asked for speculation :)
Conversely, anything else is a good choice for startups because most start-up fold and will never have to actually fix all of the memory leaks/security vulnerabilities/slow implementations.
Necessary, but not sufficient. Almost all the startups with bad implementations will fold. Almost all the startups with good implementations will fold.
I have also used Rust in a startup. With one major exception, it has been a huge win.
Rust makes it incredibly easy to write fast CLI tools and special purpose servers. They're solid and pleasant to maintain. Refactoring is easy, and if code compiles, it's normally correct.
The biggest drawback we encountered was when we used Rust for business logic. Business logic tends to be high level and change frequently, and many different people need to touch it.
So we ended up with a split: Most of our business logic is written in popular high-level languages. But for those things which aren't specific to our business, we write lots of open source Rust.
Many good points that I'm able to relate to. However, the post is too exaggerated, e.g.:
> The amount of debugging required for Rust projects is an order of magnitude less than I’ve seen anywhere else.
Sorry, that's just nonsense. I've done a large amount of .NET and Java and a good amount of Go and Rust. Stating that debugging effort in other languages is at least 10 time (which is an order of magnitude) higher is a huge exaggeration.
Also, one absolute critical point is missing: The reliability of the ecosystem. That's the biggest weakness of Rust. Rust's NPM like ecosystem is just brittle and dangerous. There're enough examples of widely used crates that caused issues due to maintenance or that had malicious code. For all the undeniable benefits Rust brings, this single big disadvantage makes it actually not the best choice for startups.
yeah, I love Rust but this rings hollow for me too.
debugging python is a pleasure compared to Rust, and it makes sense that this is the case... Rust itself performs well because of the compilation stage to native code, but it gets harder to step through because of that.
> What does this have to do with startups though? Well, high performance means fewer servers, fewer servers means less operational overhead. As a startup your runway burns up pretty fast if you start spending it on web servers that can only support a few hundred requests per second each.
This is the most interesting part for me. Not the specific numbers, but the general notion of "performance actually matters". There's impact on ROI, UX, complexity and sometimes it lets you do things that you wouldn't otherwise consider.
There was a post fairly recently on here, where they showed a deployment architecture of a small business or startup. It was a simple thing, with a couple of app servers, databases and load balancers. Something like that. The app servers were written in Python/Django I think. The essence was that "this is a simple architecture on relatively cheap VPS instances with minimal complexity and it handles a ton of traffic", I think the bill was a couple hundred or a month maybe 1/2k max. I liked it.
But even then I thought that there has to be some overhead that can be cut there. If your app server plus database performs well _enough_ you can run them on just one instance, you can cut several load balancers. All you need is a backup machine if you care about downtime, especially during deployments. That would roughly cost you maybe 5x less. Then you might actually be able to cut down the performance of the machine, another factor of 2. Now your bills are 10x less, you have fewer things to worry about, possibly less complex tools needed.
So let's say a single developer can save them 1k (EUR/$) monthly, that would be 5-10h work hours gross, or just say a day of billable work, every month that they get out of it. And this is not considering the gains from reducing the complexity and setting themselves up for finer grained improvements and other benefits that were not possible before.
I'm not considering the downsides and the estimates are shaky at best. But there might be something to this, even for fairly small teams and companies.
Amazon did a nice write-up this year related to your comment : "Sustainability with Rust"[1]. The cost savings are there, both for a tiny startup, like you calculated, but also for giant companies with 1000+ instances.
I’ve been using Rust as a hobbyist since 2015. I see what’s going on in the community, attend a meetup, and work on open source projects (mostly my own).
I’m starting a side project, and after much consideration, I went with F# and AspNetCore. The maturity of the framework and solutions for web is hard to ignore.
And then F# gives me a lot of what I like about Rust: union types, pattern matching, avoiding null… With less syntax, and without reasoning about lifetimes, which still takes me more effort than I would like.
Don’t get me wrong, I love Rust. In this case, I was able to build out a web server a lot faster, while still getting _most_ of what I love about Rust.
Are you using ASP.Net Core straight up or through something like Giraffe? Also are you using JS or Fable/etc to handle the front end? The F# web ecosystem is something that I've done light research on but haven't done a real project with yet, but still incredibly curious about it.
I'm using Giraffe. Building everything in the request pipeline as composable handlers has been nice.
For the front end, I have decided to do server-rendered pages, using Giraffe.ViewEngine. So the source for the HTML is all F# code too.
For interactivity and updates without a full page reload, I am using htmx. This has been so nice that I feel “done” with SPAs as the default choice for a web UI. 99% of the JS I need is encapsulated in a library. If I ever need more, I can just incrementally adopt Vue or something similar on a page that needs it and go from there.
I’ve been working on an OS project to help people get on this bandwagon: create-rust-app [1]. The folks over at shuttle.rs also wrote a blogpost around a similar topic which was a very interesting read as a rust developer. [2]
This is great, it looks like it does a lot already and I really like the plugin system. I think you should definitely get the documentation written up.
One thing, the "Walkthrough" video in your README is unwatchable, because it displays very small. I had to download it to be able to watch it properly.
No mention of the type of problem the startup is trying to solve. A performance hungry desktop app? A web based SAS? Not all language choices are equal.
I may have significant input on a green field project, which is generically a web use case, but performance will be a factor. I'm interested in pitching it, as I know other teammates will be be, but none of us are particularly skilled in writing Rust. For instance, the largest thing I've written is still half baked which happens to be a basic REST API for a personal project. I have only begun to see some of the benefits you explain in your article.
I'm curious if you feel that it's necessary to have an "expert" or experienced Rust developer on the team for it to be the technology of choice; or do you think Rust has sufficient guard rails for a team with basic understanding of mature packages and overall senior experience? The reason I ask is because I've known several teams pick up Go because of their interest in it, ultimately being happy with the choice, but have strong opinions about their initial implementations.
Perhaps that's just the nature of software, but I would love your opinion.
No worries, here's my opinion (lots of lang-war stuff, so note "opinion"):
I would say that it depends on your comfort with async code in Rust since much of the web ecosystem is built that way.
If you're comfortable writing async Rust then go for it, the guard rails are there. People complain (especially here) but it's fine. Our entire web backend and our scheduler applications are overwhelmingly async. We have not hit the weird stuff you read about with lifetimes even once.
However, it does expect you to know how it works. You need to understand what the async runtime does otherwise it will add friction. If you're not yet proficient with this part of Rust then you will benefit from having an "expert" on the team as you say, since they can guide the rest.
Our team were all experienced in Rust already when hired so we didn't hit this. If you're uncomfortable then simply choose the language your team already knows. That's the pragmatic choice.
The technical aspect of a startup hardly even matters as long as you get the job done. The first thing to understand before you start a startup is that it doesn't matter how much you love programming. It doesn't matter how beautiful your code is or how much time you spent writing it.
What matters is marketing. You can use Rust or JavaScript or whatever language you want but if you want to be successful, you will spend more time thinking about how to market. Customers don't care what language a product is written in (unless it's a developer facing product). Customers care about getting the job done.
I know the argument here is that Rust offers long term stability but if you are a startup, you will be changing the product so rapidly and adding more and more features, the sheer level of growth will make your product unstable.
I am not against someone using Rust for their new startup IF they are already comfortable in it and know the ins and outs of Rust. Rust is way more complex than JS. The learning curve is considerably steeper. And that matters because if you use a great language and write it poorly, no matter what guarantees it offers, you won't get a better product than if you wrote it in a language you understood well.
So if you are a startup, don't think about the language. Think about what will sell, how you will sell etc. If you can't sell it, it doesn't matter if you wrote it in a particular fancy language. The technical aspects of a product are rarely a sales increasing factor.
When you're building a product you definitely want to spend your time fucking around with all the object lifetime concepts of Rust or the subtleties of its compiler...
Just use any language with high-level features like a garbage collector, bignums by default and message passing concurrency (Racket, Erlang, whatever), and you will be more productive, and actually have more "fearless" / safe programming than you will ever have using Rust.
> But you really don’t need much more engineer time than using another language, and you get the lower overhead when you actually run your program.
That seems like an extraordinary claim to me. That would imply that when picking something like Django, Rails or Spring over Rust, there's no difference in engineer time taken to add a new feature.
So, go with a boring technology that the existing team is already familiar with, and that fits your use case.
There's nothing wrong with PHP, Python, Go, JavaScript or Java. Even modern "no code" tools such as Bubble can get a first version done in a minimum amount of time.
I’m new to Rust and partly evaluating it for future projects at a startup, and I think I could definitely see using it selectively where it’s strengths really show. We use Go in that way as well but stick to dynamic languages in other areas. I would hesitate to go all-in on Rust given hiring is already one of the biggest challenges startups will face, but I believe Rust is going to be hugely successful and the pipeline will grow considerably in the coming years.
> Once I started working on more complex systems such as a distributed job queue with asynchronous behavior or an embedded system interfacing with an FPGA, the gains started to come.
This makes me take the advice with a grain of salt because it's not very representative of the kind of software development most startups will require. I'd be more interested to hear about startups using Rust for CRUD apps for example.
Two days ago I started to rewrite an api I made years ago in Nuxt3. The day after I finished it. Sure, I know javascript and I could reuse a small bit of code but if I would imagine switching to rust it would probably take me at least a month mostly because I don't know much about it.
The times I've actually tried Rust out it's been a struggle, to say the least, and I am a programmer with over 10 years of experience. Ok if you are the VC-funded kind of startup that needs developer hype and can afford to hire people. But if you are a bootstrapped startup I barely can think of worse languages than Rust to start with unless you've extensive experience in it.
The crates available seems sparse and of low quality. Getting back to my example, I would have to rewrite a parser from scratch most likely and only that would probably take me quite some time while in node I can just npm install it which have worked flawlessly for years.
Unless you're in a market that requires the service or product to utilize every cent of performance or is in embedded industry I think Rust is a terrible choice for a startup.
I guess it works for a fully remote company, as you have a large pool of possible candidates. But in my area, I'd say it would be easiest to recruit using java. Next python or node/js, but still a vastly smaller group compared to java devs.
That's a good point, but I'm actually not so sure about it. I think that perhaps most startups need a tighter group and alignment than what remote can provide. While I'm a fan of remote work, I'm not sure if early stages is the correct time?
Also, it can also be a pitfall that people want to work for you based on the cool tech, and nothing else. Which means they might be quicker to jump ship to the next cool thing and not in it for the long run?
However, because Rust cares about who owns things, it gets to have all the benefits you get with say RAII types in C++ except seamlessly (in safe Rust anyway).
Imagine you make a Doodad, like you call a constructor for it maybe, or there's some call somewhere that gives you a Doodad. OK. Now you put the Doodad in a Hashtable of Doodads. Well, is that still your Doodad? Are you responsible for ensuring it is properly cleaned up at some point? Or does the Hashtable now take responsibility for it? If somebody looks in the Hashtable, do they get back the Doodad? Now is it no longer the Hashtable's responsibility?
Rust systematically has answers to all these questions, which permeates the language and its ethos, in exchange it gets to have really nice properties.
> the Java GC (still in 2022) is often a major headache in production wrt latency when system is under load.
Can you say a bit more about your experience regarding this? In my experience, it is either not due to GC, because it is really hard to make the G1 GC miss its target pause time, or there is an easily debuggable function creating way too much object, and the fix is often trivial.
Like, the JVM has the state-of-the art GC implementations.
Rust doesn't have a mark-and-sweep GC. It has "automatic" memory management through static analysis. Rust's memory management is done by the compiler automagically inserting free() in the same places that you would put it manually in C.
I would add that it inserts free similarly to C++’s RAII, and it also have reference counting wrapper type which will free at runtime. Reference counting makes different tradeoffs to mark-and-sweet GCs, they usually have worse throughput, but better latency (when they are shared between threads, every new/lost reference does an atomic increment/decrement which is very expensive and happens on the working thread. Java’s GC for example can amortize this cost by doing the work almost completely in parallel)
It's not quite RAII, because it's not scope-based. Rust has exclusive ownership with moves by default, so it avoids having a concept of an accessible moved-out-of value that still has to run destructors redundantly.
It's not based on reference counting. It's possible to implement reference counting in user code (like C++ shared_ptr), but that is still notably different than languages that use reference counting as their primary memory management strategy (like Swift or CPython). In Rust reference count increases are manual, and refcounted values can be borrowed and safely passed around without updating the reference count.
Have you ever wondered what a "moved-from" object [0] in C++ contains? In Rust, such objects are inaccessible due to enforcement of the compiler. In C++, they are accessible. Have you ever wondered what performance implications that has? Have you looked into what the C++ standard tells us about "moved-from" STL objects, what state they are in?
There are good use cases for requiring the moved object to still be valid and accessible, such as when memory lifetimes are decoupled from object lifetimes. It enables some optimizations. The specific state depends on the design of the type and its use case.
As someone using Rust for a "startup" (not hyper-growth but slow and steady) there are definitely upsides and downsides.
The biggest upside is that the stricter compiler does catch bugs. It makes changing existing code easier and it makes it easier to add invariants across the code via the type system. It makes an extensive test suite much less necessary, generally unit tests for pure parts of the code and some form of simple dev/staging environment will suffice. This can defer the need for expensive and slow integration tests running on every change.
Performance is also nice but it doesn't matter much. My service is running with 10m cores and 50MiB of memory, 10x those wouldn't be a major concern. I think that in 99% of cases performance only really matters when you are trying to optimize running costs and that is generally only the case when the operational costs matter relative to the cost of an employee. The performance of your application is very rarely related to the performance of your application code, usually it lies more in the database and network calls that you perform while serving requests. I think for many startups the cost of actually running your code tends to be tiny compared to staff and other infrastructure. The docker image is 160 MiB (with debug symbols) which is probably smaller than most Java/Python projects but not tiny anyways.
There are definitely cases where Rust is more verbose than Python (over Java I actually find Rust more productive) but even if you can write very high-level code with Rust part of the problem is that it doesn't necessarily encourage you to do so. With things like explicit `.clone()` calls and reference counting you are very aware of every time you make a performance tradeoff. It takes the right attitude and personality to say "that's fine" for most of these cases and leave the optimization to when it matters. (When you do want to optimize it is very clear where all of these expensive operations are which is nice.) But something like Python where these slow operations are completely hidden is definitely nice for focusing on the business logic.
Overall I think it is legitimately a close call. I definitely spent more time worrying about unimportant details with Rust but I likely would have shipped more bugs and had a harder time making wider changes. I would also be much less confident with the stability of the current code which is very important to me as this is running as basically a side-project without a 24/7 oncall. Also the more cross-cutting features I add the happier I am with the type checking.
I think Python (with a type checker) or TypeScript would have been slightly more productive but I think the investment of Rust was worth it. The fact that I can see the path forward with no rewrites or the need to break off expensive components into microservices in higher performing languages is a really nice outlook.
I'd say with a caveat it depends if you know what you need to build. You can have 0 bugs, but if you also have 0 users, it's not going to end well.
If you've already built a slow or not-so-reliable prototype in a scripting language, and have users pushing it beyond its limits, then go ahead and make the proper version in Rust.
Unless Rust itself solves a problem specific to your startup, I'm not so sure. I like Rust, but the language seems very complex compared with Ruby or JS, so your talent pool will be considerably smaller and probably more expensive.
Startups should hire the kind of people who are experts at both C++ and Javascript, then ask them to choose the right tools and languages for the task at hand. Which I am sure may end up sometimes including Rust.
This is hilarious, it is a great choice for start ups, to do what? How is it that what you do isn't the first thing that affect your choice of technology, but the "type of company" you are is?
Is there a mature, production ready library for deploying deep neural networks in Rust? Searches end up being all over the place and end with a library that hasn’t been maintained in years.
Rust is the one ring to rule them all. Embedded? Got it. Huge web app? No problem… straight to wasm.
It’s hard to imagine a problem outside of machine learning (where library support is all that matters) where I’d ever feel a desire to use anything else.
Other languages feel primitive, slow and/or unreliable after using rust for a while.
> Other languages feel primitive, slow and/or unreliable after using rust for a while.
But the fact is that that is just feelings. Rust is a cool language, as well as a litany of others. It is unique in the low-level PL domain, but at most places managed languages can be used just fine, and I would wager that they are a better fit for regular old CRUD apps.
In fact, NO LANGUAGE is a great choice for startups! You don't choose languages depending on whether you're a startup! You choose languages based of the problem you're trying to solve, how fit the language is for solving that particular problem, the ecosystem supporting that language, and the availability of developers who are experienced with that language.
Rust just may be the best choice for your startup, but it's not necessarily the best choice for all startups - in fact it's probably not the best choice for most startups! That doesn't mean there's anything wrong with Rust, it just means Rust isn't the right tool for the job most startups are trying to tackle. If it is the right tool then absolutely you should use it!