One weird thing about rust is that network sockets and file handles are automatically closed when the handle drops out of scope. The borrow checker takes care of that. If you do the same thing in JavaScript (open a socket then do nothing), the program won’t even quit on its own and you’ll have no idea why.
> One weird thing about rust is that network sockets and file handles are automatically closed when the handle drops out of scope. The borrow checker takes care of that. If you do the same thing in JavaScript (open a socket then do nothing), the program won’t even quit on its own and you’ll have no idea why.
That’s not an inherent problem of GC. You can have linear types or destructors in a GC language.
EX
using (SomeKindOfHandle handle) {
// handle releases when the scope ends
}
I worked on an application with extjs that the workers had to close and reopen at least once a day. Or unofficial instructions were portable Firefox.
I think the borrow checker has an unfair reputation of being complicated and magical. Its rules aren't always obvious to a beginner, but at the end of the day it's just type checking / static analysis. People often imagine it also does things at runtime, or affects code semantics in some way. It does not. And it's only scary because because it's so stern :)
* You can trivially make objects immutable. That feature is tacked on to most GC languages (e.g. Object.freeze) and rarely used, if it's even available. Again mutability of everything encourages bugs.
* You can easily copy values.
* You can use RAII to deterministically and automatically clean up resources, and guard things (e.g. using mutexes).
These features are all in C++ too but Rust lets you have all that and memory safety (and it's better designed than C++).
A classic bug that you wouldn't see in Rust might be passing a list into a function and the function mutating it when you weren't expecting it to. Basically impossible in Rust.
On multiple teams of FAANG engineers, Ive seen the GC be a big part of some meltdown and none of us knew a good way around it. Tuning only goes so far. Otherwise, you just have to give it more memory and CPUs (horizontally or vertically).
Almost always the answer was, this might need to be reworked in C++ entirely or JNI. In same cases it even got funded and was a tremendous success (like 10x fewer resources). However, then you’re dealing with C++ and all of its issues.
I’m looking forward to more value types in Java but managing the heap will always be a bottleneck eventually.
For C# a single executable over a directory of files. For that and Java, a massive runtime, generally slow cold starts, high initial memory use, reduced relative effectiveness for smaller platforms (RPi and similar).
For JavaScript and Python, slow introp, in addition to the negatives above.
It's also possible to leak memory like a sieve in any language.
- .NET had been able to produce single-file (and self-contained when needed) executables way before NativeAOT was introduced
- RPi is a fairly large platform compared to e.g. Arduino (for which Rust should be awesome) and can be well-served by NativeAOT (today). I might still use Rust for that one in the long run but using C# wouldn't be an issue both in terms of resource usage and OS since it's just an arm64 musl flavour of Linux usually with 1GB of RAM or more which is a lot for .NET (for context ~256MiB containers with ASP.NET Core image is a popular target for back-ends)
PTC, Aicas and microEJ are still around, placing Java in hardware that .NET will never be, even with Meadows.
Panama main goal is to replace JNI performance warts, while Java / ART has had mechanisms to do fast interop (@FastNative and @CriticalNative).
Do you have references that say otherwise? (I know you don't, it has JNI level of performance)
p.s.: you have to be insane to use Java today on those listed platforms, which are much better served by C and now Rust. RPi is as small as it gets and on that I'd rather never touch any Java tooling because liking it is literal Stockholm syndrome - it is as low bar as it gets and almost anything else is better.
p.p.s: for anyone's interested, here's the JEP for Panama: https://openjdk.org/jeps/424 do give it a read, then look at C# spans and interop API and ask yourself whether you want to look again at Panama without gouging your eyes out.
I do agree Panama UX could be much better.
On the single executable, my understanding is it sad kind of like a self extracting archive that extracted and ran... Meaning slower start times and the need for write access to the file system... Not to mention the framework still needed to be installed. And only more recently was true single executable possible.
You just give the users an exe or unix binary and it runs.