Live data from Hacker News

I love building a startup in Rust but wouldn't pick it again

propelauth.com

91–100 of 496 posts

Re: I love building a startup in Rust but wouldn't pick it again

#91

I can't get it why people would prefer to add "?" to everything instead of just having exceptions which automate that behavior. In the bad old days of C there were two kinds of programs: programs without correct error handling, and programs where half the loc are unhappy paths that do what exceptions do... with a huge amount of work. Today people are repeating the same mistakes of the past, putting a "?" on everythin…

Exceptions make it considerably harder to reason about state by reading the program text. As the notion that programmers should have some actual understanding of what they write slowly becomes less unfashionable, language features that make understanding code needlessly harder are losing some of their appeal even though they speed up writing the code.

Re: I love building a startup in Rust but wouldn't pick it again

#92
post #32

I've been writing Rust professionally for a few years now and if there's one thing I've learned it's that if you ever write a function that takes a parameter of `impl Fn(&Vec ) -> &'a str` you are going to be in for some pain. Just make it `impl Fn(&Vec ) -> String`. It is highly unlikely that the extra allocation is ever going to be noticed in the performance. Just because Rust pretty much forces you to be explicit…

> It is highly unlikely that the extra allocation is ever going to be noticed in the performance. I had almost this exact scenario, and yes there is pain in writing it with explicit lifetimes. But I can't agree the performance improvement is negligible; maybe in isolation, but I saw about a 100x speed increase for my application when I switched away from Strings. For me it was because I was doing many of those extra…

This is not an uncommon pitfall when working with strings in all languages. In Java for example it is drilled into people to use StringBuilder instead of concatenating with + on String if you do it in a loop, precisely because of this exact issue.

Re: I love building a startup in Rust but wouldn't pick it again

#93

Earlier quoted context omitted.

I prefer having extra work done writing code (adding "?") than having to do extra work reading code. Exceptions are functionally invisible control flow; it isn't clear to the reader that a function may blow up if the exceptions are unhandled.

Assume all functions can throw and there is no extra work reading. A function that has no possibility of error is so uninteresting in the context of error handling. Furthermore, handling errors has little to do with where the error is actually caused. In general, you can only do two things with errors: log and kill the operation or retry the operation. Neither of these has anything to do with the leaf function 20 ite…

> A function that has no possibility of error is so uninteresting that focusing on that is the wrong thing.

I disagree, a function that has no possibility of an error is a proper function, and what we need for performance optimized code.

Proper functions by definition are just mappings from a domain to a range. That mapping really shouldn’t be predicated on any other state, so it should never fail if the inputs are valid within the domain.

We need to focus on such functions if we want performance, because we can only achieve too speeds by not worrying about checking the function result for correctness. Given a proper function, we should just be able to compute the result and move on to the next function.

Therefore it’s of great benefit to us (as authors of performant code) to separate our fallible functions from our infallible ones. Keep the fallible ones iutside of hot loops, only infallible ones inside, and that’s a recipe for mechanical sympathy of the sort that results in great performance.

Re: I love building a startup in Rust but wouldn't pick it again

#94
post #37

If you're thinking about building something in Rust, a good question to ask is, "what would I use if Rust didn't exist?" If your answer is something like Go or Node.js, then Rust is probably not the right choice. If your answer is C or C++ or something similar, then Rust is very likely the right choice. Obv, there are always exceptions here, but this helps you work through things a bit more objectively. Rust can be a…

Not sure I agree with Go vs Rust. I think if you would choose Java or Python or C#, then Rust might not be the right choice.

Go is in a sweet spot where it is often used to compete with both groups: [Rust, C/C++] and [Node, Python, Ruby, etc]. The reason GP said it is probably because of Garbage collection.

I've done a bit of Rust in my job, and there are some basic things that Rust doesn't have going for it:

- steep learning curve (this means for the first 6 months, you or your colleagues are unproductive, write bad Rust which your company then builds upon over time).

- bad error messages (even though that was a focus for the rust team!)

- frustratingly complex for setting up test coverage

- Slow analyzer speed (*super laggy* on Clion, though this might be a jetbrains issue)

- Slow compilation times (I heard somewhere that "Go just goes". I've also written some Go in my free time, and compilation is fast. Well IMHO, "rust will rust" - it's very slow. Generics can make compilation event slower.)

- Verbose. I've seen a just few lines of JS get replaced with hundreds and thousands of Rust.

Re: I love building a startup in Rust but wouldn't pick it again

#95
post #70
post #19

Earlier quoted context omitted.

I get where you are coming from, but imagine if every other "to the human" process description we had was done this way. I actually think this would be a fun one. How to make scrambled eggs, but where all failure cases are covered. Would be the "Hal fixes a lightbulb" in prose.

That gets to the original promise of computers, doesn't it? That they'd perform repetitive tasks quickly and reliably. Meanwhile, every time I make scrambled eggs, there is a small but very real chance that my house burns down. And we accept this because to err is human .

Sorta? But a lot can be packed away in "other directions." Most recipes, for example, assume that setup/teardown is intrinsic to the kitchen. As such, to know the procedures to do those things, you would look somewhere else.

That is, you aren't accepting a risk that things will go wrong. You have moved what to do about many exceptions to somewhere else.

Re: I love building a startup in Rust but wouldn't pick it again

#96

Earlier quoted context omitted.

Go belongs in the exact same bucket as Java and C#.

C# sure, but unless you are doing something pretty close to the core purpose of some giant java framework java is slow and verbose

Slow and verbose compared to what?

Re: I love building a startup in Rust but wouldn't pick it again

#97
post #13

I have the same impression of Rust: great for software that is well scoped/defined and needs to be stable and efficient, not so much for quick iterations (which for startups is important) and software that doesn't need top performance. I think in general that the Rust hype has outgrown what it's good for. If you're writing a web app in Rust then you may want to ask yourself if you're making the right choice.

For simple applications, Rust is actually pretty easy to work with in my experience. You don't get a lot of comforts other languages provide, but you don't always need those.

The performance difference between a Rust server and other languages are incredible, especially in terms of RAM usage and concurrent connections per second.

That said, if your program is going to need tons of entities stored in a database, I wouldn't even consider a language or framework without a solid ORM. Rust has some ORM-lite libraries but I'd end up picking a garbage collected language in practice just because of the difficulties that low level programming bring to such middleware.

Iterating in Rust isn't that hard as long as you don't try to cheat your way out. Instead of returning null for methods that you haven't implemented, add a todo!, etcetera. You have to do things somewhat right the first time. I think that's good, because there's nothing as permanent as a temporary proof of concept. You can clone/copy your way out of most annoying Rust restrictions at the cost of performance you'd otherwise sacrifice by picking a higher level language anyway.

If your startup doesn't know what it's building, you have bigger problems than the language you choose.

Re: I love building a startup in Rust but wouldn't pick it again

#98
post #14

Earlier quoted context omitted.

In Java functions declares Exceptions in its type signature, so it does all of that automatically. Then you get a compile error if you don't handle it in the function, or you need to declare the function throws it, so it is type safe. Note that people now consider that as a mistake, people prefer having Exceptions be hidden instead of explicit and requiring handling like that.

> Note that people now consider that as a mistake Correction: Some people. Java's checked and unchecked exception approach is quite nice if used judiciously. It certainly beats checking for error after every function call (default: mostly people ignore error codes) and you even get typed errors so you can trivially incorporate exception handling in the conceptual design as a first class design element. I am frankly n…

The greatest secret of exceptions is that in most cases you don't need to catch them. What should really be on your fingertips is

   try {
      ... something ... 
   } finally {
      ... clean up ...
   }
this (plus try-with-resources) is the genius of exceptions. The tragedy of exceptions in Java is that checked exceptions convert the above to

   try {
     ... something ...
   } catch(ACheckedExceptionThatHasNothingToDoWithThisCode x) {
      throw new SomeOtherCheckedExceptionToPleaseTheCompiler(x)
   } finally {
      ... do what has to be done ...
   }
with the variations of

   throw new AnUncheckedExceptionSoIDontVandalizeMyCodeMore(x)
and

   catch(...) {
      // i forgot to rethrow the exception but at least the compiler isn't complaining
   }
as well as

   // i forgot to add a finally cause because I was writing meaningless catch clauses
As much as I think checked exceptions are a mistake in Java, it is not hard to make up your mind about rethrows and apply them in a checked or unchecked form with little or no thought.

The unhappy path that you get for free with exceptions is correct for code with ordinary control flow. Most of the code has no global view of the application and is no position to handle errors. On the other hand, for many simple programs, the correct behavior is "abort the program, clean up resources, display an error message" which a sane exception system gives you for free (except for the finally which cleans up the happy path too)

For a complex control flow there is something high up in the call stack that has global responsibility. Imagine a webcrawler which is coordinating multiple threads that call fetchUrl(url) fetchUrl doesn't need to catch exceptions at all, just clean up with finally. What it may need to do is tag exceptions with contextual information that will help the coordinator make decisions. That webcrawler in particular will deal with intermittent failures all the time and only the coordinator is in a position to decide if it wants to retry and on one schedule.

Re: I love building a startup in Rust but wouldn't pick it again

#99
post #32

I've been writing Rust professionally for a few years now and if there's one thing I've learned it's that if you ever write a function that takes a parameter of `impl Fn(&Vec ) -> &'a str` you are going to be in for some pain. Just make it `impl Fn(&Vec ) -> String`. It is highly unlikely that the extra allocation is ever going to be noticed in the performance. Just because Rust pretty much forces you to be explicit…

> It is highly unlikely that the extra allocation is ever going to be noticed in the performance. I had almost this exact scenario, and yes there is pain in writing it with explicit lifetimes. But I can't agree the performance improvement is negligible; maybe in isolation, but I saw about a 100x speed increase for my application when I switched away from Strings. For me it was because I was doing many of those extra…

For sure, optimise when necessary. Rust lets you do this.

Re: I love building a startup in Rust but wouldn't pick it again

#100
post #14

Earlier quoted context omitted.

I prefer having extra work done writing code (adding "?") than having to do extra work reading code. Exceptions are functionally invisible control flow; it isn't clear to the reader that a function may blow up if the exceptions are unhandled.

In Java functions declares Exceptions in its type signature, so it does all of that automatically. Then you get a compile error if you don't handle it in the function, or you need to declare the function throws it, so it is type safe. Note that people now consider that as a mistake, people prefer having Exceptions be hidden instead of explicit and requiring handling like that.

Java isn't generic over exceptions. You can't write a method that takes an instance of Foo and says "my method throws whatever Foo.bar() throws" or even "my method throws iff Foo.bar() throws".

And this means that your method either always demands to be wrapped in a try-catch, or you migrate to unchecked exceptions.

Rust makes errors a part of the regular type system, so they automatically benefit from all its features.

Post reply on HN