Live data from Hacker News

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

propelauth.com

401–410 of 496 posts

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

#401
post #396

Earlier quoted context omitted.

It has been a very long time since I’ve used Java. Rust will tell you where you need the locks, at compile time. Does Java? Serious question.

Not since I’ve use it either. I may be missing something since I’ve only used async Rust, in what way does Rust say “you need a lock here”? If it does that then I stand corrected and I may just have to drop async Rust altogether and checkout crossbeam + rayon that everyone raves about.

Rust has two traits, Send and Sync. Send means "this can be transferred to another thread," and Sync means "this can be accessed via a reference in another thread.

Here's some (contrived!) example code (for one thing I'm using thread::scope because I don't want to deal with joining the threads):

    use std::thread;
    use std::rc::Rc;
    
    fn main() {
        let v = Rc::new(vec![1, 2, 3]);
        
        thread::scope(|s| {
            s.spawn(|| {
                do_work(v.clone());
            });
            
            s.spawn(|| {
                do_work(v.clone());
            });
        });
    }
    
    fn do_work(v: Rc>) {
        unimplemented!()
    }
This gives:

    error[E0277]: `Rc>` cannot be shared between threads safely
      --> src/main.rs:8:17
       |
    8  |           s.spawn(|| {
       |  ___________-----_^
       | |           |
       | |           required by a bound introduced by this call
    9  | |             do_work(v.clone());
    10 | |         });
       | |_________^ `Rc>` cannot be shared between threads safely
       |
Rc is not thread-safe. We try to send it into some threads. It doesn't work. Switching to Arc, which does use atomic reference counts and therefore is thread-safe, does. Same principle would apply with Mutex if we were trying to modify the vector, Rust will yell at us.

One really really nice thing about this is that it'll check no matter how for "down" into the details the thread unsafety is. There's a story Niko told in a presentation of his how he was doing some refactoring and added a type that wasn't thread-safe like, four or five layers down from where the threading happened. rustc caught it immediately, and therefore, it was obvious. Would have been a heisenbug in other languages.

Async Rust also uses Send/Sync, for example, tokio::spawn requres a Send bound, just like spawning a thread does. I do know there are some tricky deadlock cases there, if I recall? But deadlocking isn't what I'm talking about, no aspect of Rust statically prevents those.

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

#402
post #377

Earlier quoted context omitted.

"I really don't see how anyone choses nodejs/deno to anything." This is going to sound mean but I don't really know how to phrase it more nicely. People building backends in js/ts are doing so because either they, or a critical mass of the people they expect to code in it, don't know any better backend languages. I don't mean for this to be judge-y. People have different skillsets. A nodejs backend can be the right c…

I love Rails and if it was continuing to grow even so slightly it will be my go to for sure. But unfortunately it has been slowly declining for a long time… Many moving to Go, Elixir, Rust, and elsewhere. It was by far the best dev experience with a framework I ever had. The last version still looks great. But realistically unless if you plan to do a rewrite, which is never a good idea, it may not be the best option…

> But unfortunately it has been slowly declining for a long time…

That could be a sign of “stability”.

I’m personally using Django since two years ago and have the same feeling as yours, there are nothing exciting happening in this area, but after two years of use I came to the conclusion that it’s features are too stable, so nothing new need to happen in the first place.

It’s a common myth that software should be always updating and introducing new features. No, it’s not, if it can solve the problem great it doesn’t need to change at all.

JS/TS/Rust are still in their exploration phase, new ideas, new exprimentations, new frameworks come and go everyday, and that’ the reason they look vibrant.

Before settle down with Django, for years I’ve used bleeding edge tech like Meteorjs/React/Nextjs/Vue/Nuxtjs/Svelte/SvelteKit/… in real world, or try to rewrite real world app with them, and the biggest problem of all of them is that they all have their quirks and things in JavaScript area are changing too often and too much, I’m so tired to chase all these fancy new ideas.

For 90% web apps Django+Htmx+AlpineJS can serve me good and do all the things that new tech can do easily, at the same time keep incredible stability.

I believe Rails or Laraval are same here, you don’t need to switch in 90% cases, just relex and appreciate the stability they bring.

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

#403

Earlier quoted context omitted.

This comment is presumptuous, dismissive, and also wrong. People who write application-like front ends in React (etc.) want back ends that can interoperate with those front ends. They accomplish things like built-time code generation, static server-side rendering, and other kinds of code transformation that are difficult and flaky without a back end that can understand JS. I have looked for non-tinkertoy solutions in…

> want back ends that can interoperate with those front ends. You can ingest and emit JSON in any language. You can even compile backend-friendly code to run in JS on the frontend, via emscripten (and increasingly, Wasm), which will output very lean and JIT-friendly code. The usual "isomorphic" case for backend.js is no less 'presumptuous' or 'dismissive' than the comment you're pointing to and criticizing here.

By using Typescript you can share types on the backend and frontend. Java stacks tend to do the same thing but for backend and database by defining data at the ORM level. You can connect to your database in any language, but most people using Spring don't write plain SQL.

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

#404

Earlier quoted context omitted.

All these workarounds for easier Result handling truly make me wonder whether Rust will eventually evolve exceptions as a feature - of-course without explicitly terming them so.

The community would revolt. Not going to happen. Proposals to make the existing syntax and semantics even look more like exceptions were met with lots of hostility.

Revolt how? Go back to C++ or whatever language/s they were using?

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

#405

Earlier quoted context omitted.

> makes cleaning up resources easier I've never really had a problem with it, but I isolate such resources behind a wrapper, which makes cleanup easy. I just create a little higher-order function: function doSomethingThatNeedsCleanup(fn) { const thing = createTheThing(); try { return fn(thing); } finally { cleanUpTheThing(thing); } } > this drives me absolutely insane (console.log(["10", "10", "10"].map(parseInt) out…

> So parseInt coincidentally matches the signature Array .map() is looking for. If that were true I'd not mind quite as much... but actually, parseInt takes two parameters and map passes three.

Map’s second and third parameters are optional. Your functions aren’t required to implement them, which is good, because most of the time you don’t need them.

Again, this isn’t a type system issue. It’s both an API design issue and a poor programming hygiene issue. (Don’t pass bare functions if you don’t know what the parameters are.)

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

#406

Earlier quoted context omitted.

It depends exactly how simple that CRUD API is. If there's any business logic, I'd rather get all the cheap correctness guarantees that Rust provides. I don't find myself making many truly dumb CRUD APIs. Time to iterate is also only much faster in certain situations, e.g. local development; if you have to e.g. build a container image, push to a registry, and redeploy to a k8s cluster somewhere, those savings become…

“Time to iterate” is measuring how quickly you can get an idea, build it in code, deploy it to your customer, and get feedback. If Rust is helping you make prototypes and iterate quickly, I’d love to hear how you’re using the language.

Not your parent, but I have some ideas on this. I'm not sure how true they are. Maybe I'll write a longer version some day and see what people think. But the summary is this:

I suspect it has to do with how familiar you are with type systems, and the way that you use them. I find that Rust's constraints help guide me towards a solution more quickly, and I spend less time chasing down strange edge cases. Not eliminate! But reduce.

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

#407

Earlier quoted context omitted.

> So parseInt coincidentally matches the signature Array .map() is looking for. If that were true I'd not mind quite as much... but actually, parseInt takes two parameters and map passes three.

Map’s second and third parameters are optional. Your functions aren’t required to implement them, which is good, because most of the time you don’t need them. Again, this isn’t a type system issue. It’s both an API design issue and a poor programming hygiene issue. (Don’t pass bare functions if you don’t know what the parameters are.)

> Map’s second and third parameters are optional.

I mean, map always passes them in, so in that sense they aren't optional. Mixing that with functions that take in optional parameters, but aren't usually called with them, gives you a ticking time bomb, IMO. And double that danger when the language's type system allows you to call a function with more parameters than it could ever take.

> Don’t pass bare functions if you don’t know what the parameters are.

This is exactly the kind of thing I want my programming language's type system to catch for me, if I'm working in a language with a static type system like TS.

And even in dynamic languages, this is exactly the kind of thing I want my programming language to catch for me at runtime. Python does, for example.

Stuff like this - while it might fit JS and TS and make sense to some - makes absolutely no sense to me, and is why I simply look to other languages to fit my needs.

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

#408
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…

I don't agree with this. If Rust doesn't exist you might have a choice between the pain and endless bugs of using C++ or the ease, but much slower performance, of js. Maybe you end up choosing js.

But if Rust exists, suddenly you have a nicer-to-use high performance language, and you have a choice to use it.

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

#409
post #20

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…

It's mostly philosophical, are you fine with blowing up with an exception, or would you rather have your functions return known values for the unhappy path? I personally like exceptions in exceptional cases, but much rather having functions with explicit contracts (e.g. "this will return either True or False in all input cases", not "this will return either True, or Exception in all cases when $foo doesn't exist in t…

Nim handles that with the {.raises: [].} pragma and the effect system, which is quite a neat approach. It’s like opt-in checked exceptions, but with much nicer ergonomics than Java used to have

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

#410
post #404

Earlier quoted context omitted.

The community would revolt. Not going to happen. Proposals to make the existing syntax and semantics even look more like exceptions were met with lots of hostility.

Revolt how? Go back to C++ or whatever language/s they were using?

I don't know exactly, but it's never pretty when a project's leadership makes an unpopular decision. Lots of complaining, for sure.
Post reply on HN