5 ms·
The answer for why folks are so inclined towards doing high-level tasks in Rust... is the type system. Its sensibilities are in a sweet spot that makes it very
by creatonez 2y ago
The answer for why folks are so inclined towards doing high-level tasks in Rust... is the type system. Its sensibilities are in a sweet spot that makes it very easy to pull off huge refactors. It was also a lot of people's first introduction to algebraic data types being used in nearly all error handling (its usage of `Result<T, E> where E implements Error` and lack of nulls or exceptions). It makes a lot of progress towards the goal of "make invalid states unrepresentable", which could be really useful for web apps.
- kortilla 2y ago>Result<T, E> where E implements Error` and lack of nulls or exceptions This all goes out the window when people throw “unwrap” all over the place because “this should always succeed”.
- creatonez 2y agoRust does not skirt around the fundamentals. You can still handle errors however you want, you can still blast side effects all over the place, and you still have to uphold an arbitrary set of invariants specific to the task at hand. But the ecosystem as a whole is filled with things being done the right way because the language and its linters have always been quite helpful.
- LAC-Tech 2y agoIn any program there are errors you can handle and errors you can't, errors whose vary existence suggests something has gone horribly wrong. What else should you do in that situation but panic?
- kortilla 2y agoI see unwrap used all of the time on things that could be recoverable if people bothered to write the control flow. “Meh, let the program crash” is easier because unwrap is much less verbose than the match unpacking or carrying results to callers. Rust has exceptions, they are just named Result and people just as frequently decide not to handle error results as not catch exceptions in my experience. Typed exceptions are just as good as what rust offers IMO.
- ActorNightly 2y agoTyping in modern days is effectively moving the task of debugging to compile/ide annotations process instead of testing for correctness. Albeit it makes the process easier compared to a really shittly written code without strict typing, but against good codebases, it takes the same amount of time.
- tkzed49 2y agoI strongly disagree on the principle that tests and types have a 100% overlap in the problems they're solving.
- ActorNightly 2y agoWhy not? If you think about correctness of a program, (i.e for any combination of given input , it changes a state in a determinstic way, including no state change for invalid input). Strict typing is one way to accomplish this. The cpu does not give a shit about types. It cares about memory registers and locations. The unique code built into the compliers/transpilers is the thing that validates the correctness of the program in this case. You can move that code into the testing suite without relying on the complier, and just do testing. Generally, given competent programming skills, this takes about the same amount of time as designing a well structured program - your tests are pretty much your design document for the thing itself.
- dinosaurdynasty 2y agoYou can not test for the absence of behavior. You can design type systems to ensure the absence of specific behaviors.
- ActorNightly 2y agoWhat do you mean by absence?
- tkzed49 2y agoThis is a very anti-pragmatic way of looking at things in my opinion. The program is not a snapshot that exists in a vacuum. Most programs are going to grow over time and have things added and removed in various places by many people. They're going to have many interfaces and operations. I think you're arguing that tests and types can both be used to check a particular case for correctness. Sure, this is true. However "moving type checking code into the test suite" means nothing—that would just be type checking. When you make a code change, there's a difference in the kinds of feedback you get from your tests and your types. Tests usually cover business logic or stories—things that you want or don't want. Types ideally cover everything. They check every operation applied to a given piece of data. Of course types are rarely precise enough that they can catch every logic bug (e.g. strings with semantics not encoded in types, like email addresses). This is just scratching the surface. You might just have to try out both to get a better sense of how they feel to work with.
- throw10920 2y ago> The answer for why folks are so inclined towards doing high-level tasks in Rust... is the type system. TypeScript has an equally powerful type system. Python's type system is almost as good. Both have are significantly more productive when it comes to writing software, and have bigger ecosystems and lower learning curves. > It makes a lot of progress towards the goal of "make invalid states unrepresentable", which could be really useful for web apps. TypeScript and Elm are both good at this while being useful for web development today.
- fallingsquirrel 2y ago> TypeScript has an equally powerful type system. How does TypeScript's type system prevent shared mutable state?
- throw10920 2y agoWhen did threading get added to JavaScript? And does Rust have type unions and intersections, interfaces, and mapped and conditional types?
- fallingsquirrel 2y ago> When did threading get added to JavaScript? Shared mutable state is a problem even in single threaded code (for example, modifying a collection you're iterating over) > And does Rust have type unions and intersections, interfaces, and mapped and conditional types? You can typically accomplish the same thing with enums/proc macros/traits of course—with the additional benefit that the type system is designed to be sound. Soundness is an explicit non-goal of TypeScript[1], so once you start layering on those kinds of overly-clever types, you soon reach a point where you're just lulling yourself into a false sense of security. [1]: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals#non-goals https://github.com/Microsoft/TypeScript/wiki/TypeScript-Desi...
- throw10920 2y ago> Shared mutable state is a problem even in single threaded code (for example, modifying a collection you're iterating over) ...which is an extremely rare source of bugs. The vast majority of errors caused by shared mutable state are related to concurrency. > usually So, not always. That is - TypeScript's type system contains features that Rust's does not have.
- J_Shelby_J 2y agoPeople who say copilot is useless.... I can only imagine they're in a dynamically typed language. Copilot + Rust makes boilerplate go fast. Strong typing is force multiplier for code gen.
- adastra22 2y agoI suspect that’s true. I never blindingly copy LLM generated code (that would be recklessly stupid), but I often only quick skim rust code generated this way, just to make sure the general task it is solving is what I asked for. If there is an unhandled edge case or or memory handling bug, rust will catch it.
- NitpickLawyer 2y agoIt's also easier to implement a generate_code -> check_for_errors -> give_error_to_llm -> fix_code loop, because the errors that rust throws at you are most of the time really well thought out, and as succint as usefully possible. Comparing it with python, where you have to write custom parsing to trim it down and even then it's hit and miss on where the actual error lies, it's not even funny.
- adastra22 2y agoRust’s compiler errors is definitely one of the selling points of the language.
- pjmlp 2y agoMost of those people aren't aware that the type system is a feature from most ML derived languages since Standard ML is a thing. All of them with better ergonomics for Web development.
- MrJohz 2y agoDo they really have better economics? (EDIT: ergonomics!) Last time I looked into OCaml, I struggled to find a way to interact with the database in a type-safe way, I never figured out which standard library I was meant to install, I was being encouraged to use 2-3 different project management tools (Dune + Esy + OPAM), and I gave up on writing tests. But at least there's a garbage collector! I realise these are all problems that I'll wrap my head around over time, and eventually they'll seem completely trivial to me, but the introductory documentation on getting started as a professional (and not as a first-year student doing a French-language compsci degree, which is what most of the documentation assumes), is pretty dire. Meanwhile, much as I'm sure I overuse `.clone()` and `[A]Rc<_>`, the ownership model of Rust is deeply useful. It's something I often find myself missing in Javascript - not necessarily because I want to produce the most performant code, but because it's useful to understand the lifetimes of the objects I'm keeping around. Am I accidentally storing a reference to something in a closure that I forgot about? When this object gets deleted, have I checked that it's the last possible reference to this object? Etc. Like, I don't think everyone needs to learn Rust. It's a great language, but there's lots of other great languages out there, depending on your personal and business contexts. But I think this idea that Rust can and should only be a low-level language feels absurd to me. It is a fairly ergonomic language with a fantastic ecosystem, a powerful type system, and an ownership model that will be useful even if you do try and opt partly out of it with GC-like wrapper types.
- pjmlp 2y agoI guess you mean ergonomics. Yes they do, unless you get your editor to magically type `.clone()` and `[A]Rc<_>` all over the place. Not to mention they don't need unsafe, or 3rd party crates to handle graphs. Additionally, all of them have interpreters and REPLs alongside their compilers, streamlining the code-develop-debug loop.