3 ms·
Agreed. Which is why I prefer garbage collected languages. Rustaceans, however, harbor an irrational fear of garbage collection pauses, hence "memory safety-fir
by bjourne 6y ago
Agreed. Which is why I prefer garbage collected languages. Rustaceans, however, harbor an irrational fear of garbage collection pauses, hence "memory safety-first ideology" built on garbage collection is heresy. The one true path to memory safety nirvana is through the holy borrows checker. :)
- mlindner 6y agoWell the set of all programs where garbage collectors can be used is smaller than the set of all programs where manual memory management can be used (either done by the compiler or manually by the programmer). This doesn't counter your point completely, but it bears thinking about.
- saemei 6y agoRust' memory safety feature includes "fearless concurrency". Popular GC languages like Java or Go are not able to prevent a class of data race bugs that Rust prevents at compile time. Languages like Haskell of course handle it much better, but are for a multitude of reasons not popularly used in production. And as the sibling comment points out, GC languages are not applicable everywhere. This discussion is in the context of the first not-C language being added to the Linux kernel. Can you imagine a GC language being similarly considered? So yes, the borrow checker is amazing. That feeling of satisfaction and confidence when the program finally compiles after a round of serious coding or refactoring is unparalleled among the mainstream languages I've tried so far.
- bjourne 6y ago> Rust' memory safety feature includes "fearless concurrency". Can you give me an example?
- ssokolow 6y agoI came to Rust for things like sum types, lack of unexpected null values, monadic error handling (Result<T, E>), and the borrow checker's ability to enable the typestate pattern. (https://cliffle.com/blog/rust-typestate/ https://cliffle.com/blog/rust-typestate/ for more on what the typestate pattern is but the TL;DR: is "verifying correct traversal of a state machine at compile time". For example, making it a compile-time error to try to set an HTTP header after you've started streaming the body.) Before Rust, I'd spent 15 years with Python as my preferred language, and I had experience with TypeScript, CoffeeScript, JavaScript, PHP, Bourne Shell, and the "used very little or very long ago, so I forgot" kind of experience with Lua, XSLT, Perl, C, C++, Visual Basic, QBasic, and DOS/Windows Batch Files. For me, it's purely about Rust reducing the amount of time I have to spend writing Python unit tests to get the level of confidence I want in my codebases without having to put up with the quirks of a pure functional language like Haskell that doesn't put high value on long-term API stability. (And yes, I do use MyPy and type annotations heavily.) It's also a big boost to the value proposition that, with no garbage collector of its own, it's easy to integrate Rust modules into my PyQt GUIs or Django+Celery web apps using rust-cpython or PyO3. Trying to hand off objects between multiple garbage collectors in the same address space without something like "serialize the whole thing, hand over ownership of the bag of bytes, then deserialize it" is a recipe for pain. Also, I'd suggest reading the "What makes Rust work" part of https://boats.gitlab.io/blog/post/notes-on-a-smaller-rust/ https://boats.gitlab.io/blog/post/notes-on-a-smaller-rust/ for an explanation of why garbage collection doesn't solve all the problems the borrow checker does.
- bjourne 6y agoI also have extensive experience of every language you mention and I have coded a fair bit of Rust too. I have over 20 years of experience in Python, C, C++, ELisp, Java, JavaScript, etc. Rust forces you to spend time and effort thinking about something that is automatic in high-level languages, namely collection of garbage. It's silly to claim that forcing developers to spend more time on bookkeeping causes fewer bugs. Testing is orthogonal to typing, and I believe that those who claim that the latter can make up for the former simply do not understand how to test software. Correct typing is the foundation for a correct program, but the lack of type errors absolutely do not indicate a lack of bugs. Logic errors that are not caused by type errors are far more common, far more dangerous, and are not caught by type checkers. > It's also a big boost to the value proposition that, with no garbage collector of its own, it's easy to integrate Rust modules into my PyQt GUIs or Django+Celery web apps using rust-cpython or PyO3. Trying to hand off objects between multiple garbage collectors in the same address space without something like "serialize the whole thing, hand over ownership of the bag of bytes, then deserialize it" is a recipe for pain. I've written a binding for CPython in Factor. There is some plumbing work for sure, but no, it is not that complicated. You manage objects created by the foreign memory manager using special tokens. The difficult part is callbacks; host language calling CPython which calls back to the host language. rust-cpython's documentation doesn't mention callbacks at all so I guess it doesn't support it.
- ssokolow 6y ago> I also have extensive experience of every language you mention and I have coded a fair bit of Rust too. I have over 20 years of experience in Python, C, C++, ELisp, Java, JavaScript, etc. Rust forces you to spend time and effort thinking about something that is automatic in high-level languages, namely collection of garbage. It's silly to claim that forcing developers to spend more time on bookkeeping causes fewer bugs. Your mileage may vary but, on average, I find the time lost to bookkeeping is dwarfed by the time saved on not having to use testing to verify invariants which are upheld by the type system. Granted, my coding style in Python was already quite similar to what Rust lends itself well to. ...plus, I just find it more relaxing to code in a language where I can delegate more of that to the compiler's type-checker. > rust-cpython's documentation doesn't mention callbacks at all so I guess it doesn't support it. First, rust-cpython is the older, less advanced binding. PyO3 forked off from it to explore more advanced API designs that, at the time, required API-unstable features only available in the nightly Rust but PyO3 now runs on stable Rust. Second, I haven't tried closures with rust-cpython yet but, for functions, the py_fn! macro is how you wrap a Rust function into something you can inject into a namespace in the Python runtime. As for calling Python functions from Rust in rust-cpython, you call the run or eval methods on the object which indicates that you've taken the GIL. I suppose, if closures aren't supported, you could work around it by using methods on a py_class!-wrapped Rust object instead. Third, I avoid C++ these days and limit my modern use of C to retrocomputing projects. It's just not worth the mental effort to write C in my projects, so I stick to binding things in ways where I get a memory-safe, type-safe binding and someone else can be responsible for stressing out over the correctness of the binding generator.