There are resources that won't be cleanly cleared on crash. Others won't be removed at all. There is also the debugging analysis and the monitoring sides of it too.
Thus avoiding shutdown logic is sloppy engineering to say the least. Same for ignoring the need to design the system to avoid crashes to begin with, including OOM ones.
This has nothing to do with ensuring your system is OK on crash, which is another side of robustness.
Off the top of my head: Poor error messages, any type checking is run on the generated code so harder to enforce properties, and if code generation is not in-language, then the base logic can diverge for different types, which is bad when you find bugs.
There is nothing nice about it. Not even in a REPL. Preventing a simple move of the cursor does not justify complexity and yet another way to apply a function.
No, I’m just an individual who was free for a few years, then started paying $7/mo (now $4/mo). Anyone can ask them to gc repos at any time. Typically needed when there’s an accidental push of a secret.
People is downvoting you, but you are correct. Rust is ideal for CPU-bound problems were performance is critical. For typical web services, not so much. It is hard to justify the extra development cost, even if hiring were easy (which it isn't in the majority of the world).
But I don’t? The borrow checker takes care of that? String vs &str is trivial to get ones head around, usually it’s really easy to decide whether you’d like to pass a reference or ownership, and worst comes to worst, sprinkling some copy/clone etc to get things sorted quickly still yields a binary that’s faster and more robust than something I can whip up in Python...
The borrow checker only checks, it does not solve the problem. In other languages the problem does not even exist to begin with.
It is not a trivial problem to solve (as you claim), otherwise we would have never needed the borrow checker to avoid memory bugs, nor higher level languages to speed up development by avoiding the problem altogether.
If you are going to end up sprinkling clones, heap allocating and reference counting, then you could have used C#, Java or JS to begin with which are plenty fast with their JIT/VMs and not think about memory at all.
Finally, comparing against Python is a very, very low bar for performance.
> In other languages the problem does not even exist to begin with
I am going to disagree here, because I've run into my share of memory issues in Python and C#/F#, and I'm sure by this point, everyone is well acquainted with Java's memory issues.
> It is not a trivial problem to solve (as you claim), otherwise we would have never needed the borrow checker to avoid memory bugs, nor higher level languages to speed up development by avoiding the problem altogether.
I'm not claiming that memory management is a trivial problem, I'm saying the borrow checker takes care of enough and the compiler/clippy hints when I do something wrong help me fix it easily enough. I write code slightly slower than I would in Python, but at the end, what I get from the Rust code is something that is more robust and more hardware efficient.
> If you are going to end up sprinkling clones, heap allocating and reference counting, then you could have used C#, Java or JS to begin with which are plenty fast with their JIT/VMs and not think about memory at all.
Rusts type system is enough to make me want to use it over dotnet, JS is a language with...some issues...that is fortunate enough to have a nice JIT, I consider it a serious choice for doing anything except web front-ends. I find C# needlessly convoluted and I dislike all the implicit mutability, but those complaints are very subjective.
The difference is that even if I have some clones and ref counts, they're rare, and the resulting binary is still outrageously fast, and has clear indicators of where to come back to and improve so as to not need the clone/reference counting/etc.
> Finally, comparing against Python is a very, very low bar for performance.
I compare against Python because that's the other language I do most of my work in.
You were talking about the borrow checker, which is mainly about memory safety, not memory limit issues.
In Python, C#, Java, JS... you are memory safe without dealing with memory management nor a borrow checker.
There are many languages running on top of those VMs for all kinds of tastes (OOP, functional, strict type systems, loose ones...). Claiming Rust leads to more robust software than any of those is an exceptional claim, but even if that were true, the key is the development cost.
A typed language is a typed language, there are other languages that are easy to get performance out of. I’m not a rust dev and I’m highly skeptical it will be used outside of firefox and a few niche projects after this initial hype train dies off. What other features would make me pick rust over golang or one of the interpreted languages?
> a typed language is a typed language
Well yeah, but not every type system is equal. For example I vastly prefer Rust's type system to C's because of Options instead of null and enums as sum types.
> what other features would make me pick rust over golang
Generics, iterators, pattern matching, etc. There's lots of features Rust has that golang doesn't; that's not necessarily a good thing but for what I do it is. IMO the only good thing about golang's featurelessness is the compile times and the standard library.
As for interpreted languages, IMO it's just better to be able to catch errors at compile time.
> Well yeah, but not every type system is equal. For example I vastly prefer Rust's type system to C's because of Options instead of null and enums as sum types.
Fair enough. But I'm not advocating using C here either.
> As for interpreted languages, IMO it's just better to be able to catch errors at compile time.
Just because you have a garbage collector doesn't mean you don't have to worry about memory management. I've see too many problems pop up because people don't understand how memory is managed in their GC'd language.
This isn’t true, in all languages with one you can ignore the garbage collector and still get work done. It may not be the most efficient but you still get work done. Let’s get a fresh out of code bootcamp grad in here and throw two languages in front of them if you want to test this.
You may be able to get work done, but I've seen actual bugs because people didn't understand how memory was managed. For example, not realizing that passing an object to a function was passing a reference, and not a copy. These are things that are explicit in Rust.
This won't result in any security related bug, you'd be updating the referenced version instead of a copied version. Both testing and use of the written code will show this "bug" if it's in fact a bug for this specific codebase. So now the question is, does rusts difficult learning curve warrant removing this "maybe" bug? There are other things to consider as well, memory fragmentation, performance etc. Have you measured the performance of code that both copies and updates?
But this is still using a hammer to screw in a nail. Rust is a systems language, it’s a junior dev move to force it into a web server. Use go or typescript for this, not rust. Just like I would write c++ for a backend unless i’m trying to shave off some nanoseconds.
>>>>It should be possible to write a wrapper that does "return the line"
>>> Is it, or not?
>> It is.
> It is not.
I'm arguing that you can write that function. What Misdicorl is saying is that it would be
fn read_line_alloc(&self) -> Result<String>
and not
fn read_line_alloc(&self) -> Result<&str>
because the &str would be an "use-after-free" situation, and Rust won't let you compile it. You need to allocate if you are reading from a file in order to be able to close (or seek) that file.
yodelshady seems to be under the impression that this means the functionality they want (single method call that doesn't require passing in a buffer) can't be implemented. It can, it just needs to allocate, the same way that you need to explicitly allocate the buffer you pass into read_line.
> A very useful function does not mean you have to use it in the hot path or for huge inputs.
I'm also arguing against it being provided in the stdlib because Rust is big in avoiding "you're holding it wrong" kind of answers, by removing the possibility to hold it wrong. Reasonable people can disagree :)
I've also found it annoying in the past. If Rust didn't have a design goal of giving programmers full control over the behavior of their code, there are several ergonomics changes that we could make to make it much easier to use, but alas, that is not the language we have and we work with what we can make ergonomic and easy to use.
I will say that I agree with almost everything you’ve said on this thread, but we did add std::fs::{read,read_to_string} for files to have this convenience. Adding something for stdin would bring that up to parity.
Somehow I missed/forgot about that addition to the stdlib. I understand why (as evidenced by the requests in this same thread), but it I'm sad it's another thing I have to look for in code reviews ^_^'
> I'm also arguing against it being provided in the stdlib because Rust is big in avoiding "you're holding it wrong" kind of answers
Even if it was true that Rust is big on that, such a function is not "holding it wrong", it is just a matter of convenience and development speed vs. performance.
For the vast majority of code it does not matter whether you allocate a few times or not. The timing difference is in the noise.
Let Rust be a convenient language rather than a PITA.
Thus avoiding shutdown logic is sloppy engineering to say the least. Same for ignoring the need to design the system to avoid crashes to begin with, including OOM ones.
This has nothing to do with ensuring your system is OK on crash, which is another side of robustness.