Productivity overhead in rust vs other languages


#1

I’m curious as to the difference in mental overhead (fighting with the borrow checker, managing types, etc.) between beginning out in rust vs being experienced in rust.

I’d also be interested to know of what productivity differences rust experts have experienced between rust and other languages on big or small projects.

I know rust is a systems language, but I was curious if it could be used in as a general goto language for other projects once if were to really practice.

This is a broad topic, but any anecdotal evidence is appreciated.

– Tyler


#2

Very hard to initially grasp the reasons behind lifetime restrictions, but once you get it, I find productivity is much higher than in less restrictive languages because those lifetimes help you reason about your architecture and almost forces you into sane design patterns.


#3

I find that many people gauge “productivity” by some sort of time until “okay, it works.” They often miss out on the bugfixing that happens later.

I am generally only slightly less initially productive in Rust than I was in Ruby, but I find that if I were to include all the bugfixing time, I actually come out ahead in Rust.

That is of course, if there’s some sort of open-source package to help, like there would be in Ruby: sometimes that doesn’t exist in Rust and so you have to write it yourself. This means it takes longer :wink:


#4

Tricky subject.

Consider that you have the following function somewhere:

fn some_function_somewhere<T:Eq>(x: T, y: T) { ... }

and suppose you have some PartialEq type that you want to use it on. I think this signature can probably be loosened, you think. So you change the Eq bound.

Say this results in a type error because some_function_somewhere calls another function with an Eq bound. So you look at that function, review it, and remove the type bound. This produces more type errors, and you repeat the process so on, and so on, though a fairly mechanical process…

…until eventually, you find yourself looking at a function which actually does rely on the fact that x == x.

Snap.

So what happened here?

By encoding various assumptions in type signatures, rust helps you validate whether a new feature fits into the existing design by forcing you to visit each part of the code that it impacts. In this manner, the type system eliminates mental overhead by letting the type system do most of the thinking for you.

…however.

Now it is your responsibility to realize and remember that the T:Eq bound is fundamentally necessary, so that you don’t make the mistake of trying to remove it again.

In this manner, one kind of mental overhead is removed; but another remains.


With regards to productivity… well, I find rust sometimes is detrimental to productivity on small projects. I find myself overengineering some solutions in ways that really don’t matter in the long run.

Whether this is due to me or rust, I’m not sure; but in any case, I suppose that, despite rust’s focus on correctness, one must retain that ability to recognize those times when a duct tape solution actually does suffice.

(such as things that nobody else besides you will ever use, which does constitute about 99% of the code I write in my discipline…)


#5

We can improve the productivity in writing little Rust programs. There are many ways to improve the std library (and even the language).


#6

There are two dynamics here. First, the learning curve. You are going to have more ‘Aha!’ moments, but you pay for them with some experimentation and reading a lot of compiler messages. It’ll take longer to on-board new users.

But once you’ve passed that threshold, you’ll get near scripting-language writing speed with much less debugging/testing hassle. Your code will mostly just work. That it will usually come within 50-75% of C/C++ performance (and can often surpass it with a bit of work) is a huge bonus.


#7

In my opinion, it can take quite a long time until you got have your basic idea translated into code, even when compared to languages like to C or C++. That’s mostly due to the borrow checker and Rusts general verbosity, which is sometimes very tedious.

However, it feels a bit like Haskell to me: thanks to to the strong type system and error handling idiom, code usually works the way it is supposed to right away, or after only a few adjustments. Assuming you are dealing with all errors and don’t have .unwrap() et al everywhere.

About the borrow checker and lifetimes, I’ll echo what many others have said: sadly, the documentation on that topic is still sparse and not all that enlightening. It takes a while, but then it just makes click and lifetimes aren’t an issue any more, as in: you rarely write code that has lifetime issues because you know to avoid them, and if the compiler complains, you know how to fix it without scratching your head for 10 minutes.


#8

I’m curious as to the difference in mental overhead […] between beginning out in rust vs being experienced in rust

Once you grasp it, rust concepts are mostly out of your way. You don’t think much about them, they just occasionally point out your mistakes. However there are many commonly used ways of writing code that are inherently unsafe, and compiler will force you to realise that. You may think of it as an extremely pedantic coworker who will not let your bad code pass code review and doesn’t care about your deadlines.

I’d also be interested to know of what productivity differences rust experts have experienced between rust and other languages on big or small projects.

Safety and correctness are generally at war with productivity. Rust will speed up the process of making your idea production ready (meaning fast, correct and safe to use), but nothing beats python in terms of converting your idea into MVP. I think this aspect is more important for small projects (where you test your idea and are not sure how it will evolve). Productivity in larger project is a result of many decisions and factors that it may be hard to assess just the language.

I know rust is a systems language, but I was curious if it could be used in as a general goto language for other projects once if were to really practice.

I am using rust for things that I need to get done right because other people depend on it heavily, so that higher time investment will pay off with less bugs. For other cases, being “goto langauge” is still mostly restricted by available libraries, not the language. Had rust had few more basics covered (orm and web framework is what matters most to me) I would use it way more. But it is a good language, so if libraries are not your problem, use it.


#9

So far as a beginner it comes down to:

  • Very hard and long learning curve. Like trying to drive a nail in a wall with you head. Especially when some logic does not work. Almost gave up on Rust ( Stop trying it for several weeks ) because of very simple feature, was being blocked by the compiler. Lucky the Rust forum came to the rescue.

  • After this: Less frustration.

  • Future ( when you know all the Rust tricks ): Less time spend on debugging.

A simple bug where you forgot to declare or did a wrong type match, can mean you spend hours and hours trying to back trace this bug ( Especially if all you have is a cryptic report from a client that x feature does not work ). If Rust even half of those issues, its already a massive productivity gain compared to some other languages.

At times i do wish that the Compiler its errors are not so cryptic. Experienced Rust users have no issue with them but as a beginner its no fun trying to make heads or tails. Frankly, unlike other languages where you can experiment ( Thanks to previous experiences in other languages ), Rust is a language where you NEED to read the book first, especially the ownership rules.

I do see Rust being more productive.