Why Rust is a great choice for startups
dailyedit.com
dailyedit.com
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!
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.
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.
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.
Which is not an extra but in fact means a heck of a lot for a language's chance at long-term acceptance.
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.
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.
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.
When in reality it may be, or it may be the worst possible choice. This is the parent commenter's point, I believe.
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.
sorry for picking on your comment in this generic fashion but I am critical of these memes not your observations:
Compute Is Cheap(where Gustafson Bariss is true)
https://en.m.wikipedia.org/wiki/Gustafson%27s_law
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.
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?
All the other services that compute hits (e.g. Postgres) are a different story, but that doesn't really matter when picking a language.
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.
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 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.
If we were talking about code, wouldn't that look a lot like premature optimization?
Build one, throw it away…
I understand why you might have got that impression, but that's a far cry from the reality
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 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.
Rust is like a piano where certain keys have been removed so you never play out of key.
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?
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.
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.
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.
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).
Which isn't to say this shouldn't be fixed. Just that there's a fairly good away to avoid the problem in practice.
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.
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.
You could just filter the CVs for Rust experience and then take the most impressive 10 or 100 to interview.
Many people are searching for Rust jobs, but few have a really strong experience with it.
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 ?
They all miss their 5 million LoC mudball at the bank, because that's all they know how to do.
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).
Not sure how a hybrid approach will work.
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.
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.
But .NET or Go are very fast for typical I/O bound workloads.
> 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.
> I'd argue that choosing Rust for most startups is outright irresponsible.
I feel the opposite and I run a startup using Rust. If I could go back I'd use Rust in more places, not fewer.
https://github.com/grapl-security/grapl
https://github.com/grapl-security/pulumi-hcp
Whish you guys success.
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.
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.)
Your plan sounds entirely reasonable.
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 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.
(I do program in Rust in my (non-trivial) hobby projects).
> 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.
Also, for me Rust's speed is one of the benefits. I would default to Rust for a lot of different things where speed doesn't matter at all.
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.
Just IMHO.
It sounds like Ocaml would do just as good of a job here.
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.
"Unix system programming in OCaml",
https://ocaml.github.io/ocamlunix
Ever heard of MirageOS, and are you aware that DockerDesktop TCP/IP stack uses parts of it?
Ocaml is great, but its Windows support sucks, and that makes adoption hard in a lot of contexts.
[1] https://doc.rust-lang.org/beta/rustc/platform-support.html
Rust support for them is pretty much WIP.
And then there is the whole matter that Windows shops love to ship binary libraries.
Why do you think I mentioned WIP?
The competition bare minimum is MFC, ATL, WRL, including Visual Studio tooling.
The ecosystem, even though Rust's ecosystem is still very poor when compared to Java's.
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 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).
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)
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.
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'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.
Two counter points:
* 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.
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...
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?
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.
There are ideas like that
https://it.slashdot.org/story/22/06/13/0134242/two-tech-ceos...
https://en.wikipedia.org/wiki/Manual_memory_management
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.
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.
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.
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.
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.
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.
I always enjoyed the mystery. It's a puzzle with an as-yet unknown solution. How can you not love it?
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 :-)
(That said, I coded C from 2008 to 2012, and spent no hours on segfaults then, either.)
Scala has the same problem. Stop writing your own DSLs!
100% disagree. Writing custom DSLs is how you get the best programs.
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.
Those points are hardly Rust specific and apply to any compiled language with ML influences.
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
From the official Rust lang book, Cargo section: cargo new my-project
I guess it's a matter of taste...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.
(edit) added 'tools'
Have you got any data to support it ?
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.
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++.
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 have only experienced the opposite: That Rust jobs pay well. Also for startups.
[1] https://insights.stackoverflow.com/survey/2021#top-paying-te...
edit : adding link to all previous years https://insights.stackoverflow.com/survey
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. :-)
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.
For hiring, what you should look for, first and foremost, is competence. Curiosity is not a substitute.
- they’re senior level in another language and have at least one non-trivia project in Rust (need not be professional)
- Applying for a junior position and thus will have access to mentorship
I don’t see what the problem is. Rust isn’t Haskell: while there’s a few new things, most imperative programming experience will translate.
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.
If you have a good idea and you hire seasoned developers who can realize this idea you are at least on the good path.
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.
> 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.
I sometime wish Rust and Go had a baby ...
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.
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.
[1] https://aws.amazon.com/blogs/opensource/sustainability-with-...
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.
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.
[1] https://github.com/Wulf/create-rust-app
[2] https://www.shuttle.rs/blog/2021/10/08/building-a-startup-wi...
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.
Here's a link to our Show HN from a week ago: https://news.ycombinator.com/item?id=31630604
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.
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.
Unsubstantiated claims like this, just makes me stop reading.
aot language implementation based-on llvm, guess something like clang?
Then guess it depends which Python and Ruby language implementations, what exactly we need to do and how much we can call C libs :-)
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
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.
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.
The language is fucking great. But the ecosystem isn't there yet and you have to re-invent the wheel again and again.
This applies to most startups.
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.
An in-progress full-stack framework for Nim: https://github.com/jfilby/nexus
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 think this is what actually makes your development efforts go smoothly. Not a language choice.
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.
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.
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?
Just speculation on my part.
- better type system
- better type inference (bidirectional)
- better/standardized package manager
- better error messages
- memory safety
- thread safety
There are downsides but it’s an improvement on balance. I use both extensively.
> better type system
> better type inference (bidirectional)
how do you quantify "sane" and "better" here ?
Rustian Garbage collection
Genuinely curious here: the Java GC (still in 2022) is often a major headache in production wrt latency when system is under load.
How's the Rust GC in that regard?
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.
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.
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.
[0] e.g. `b = std::move(a)`, what is in `a` now?
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.
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.
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.
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.