←back to thread

253 points chhum | 7 comments | | HN request time: 1.165s | source | bottom
Show context
nelup20 ◴[] No.44009800[source]
I personally appreciate Java (and the JVM) much more after having tried other languages/ecosystems that people kept saying were so much better than Java. Instead, I just felt like it was a "the grass is greener" every time. The only other language that I felt was an actual massive improvement is Rust (which so far has been a joy to work with).

It's a shame imo that it's not seen as a "cool" option for startups, because at this point, the productivity gap compared to other languages is small, if nonexistent.

replies(6): >>44009912 #>>44009928 #>>44009952 #>>44010109 #>>44010282 #>>44010468 #
bsaul ◴[] No.44009952[source]
Funny. I've been trying rust for the past 2 months fulltime, and i'm really wondering how you can call it a "joy to work with" when compared to java, at least for server development.

Rust feels like walking on a minefield, praying to never meet any lifetime problem that's going to ruin your afternoon productivity ( recently lost an afternoon on something that could very well be a known compiler bug, but on a method with such a horrible signature that i never can be sure. in the end i recoded the thing with macros instead).

The feeling of typesafety is satisfying , i agree. But calling the overall experience a "joy" ?

replies(5): >>44010045 #>>44010053 #>>44010107 #>>44010130 #>>44012365 #
treyd ◴[] No.44012365[source]
You eventually learn you leverage lifetimes. You just need to get over that point in the learning curve. I very rarely run into those types of issues, and it's very freeing knowing that I can write libraries that are so hard to misuse because you can leverage the type system.

And macros are a part of that!

replies(2): >>44012714 #>>44012800 #
1. rwmj ◴[] No.44012714[source]
Why do I need to? Why can't I let the garbage collector deal with it?

Rust's macros on the other hand are excellent, and more languages should have expressive macros like that.

replies(2): >>44013927 #>>44017830 #
2. bitwize ◴[] No.44013927[source]
> Why do I need to? Why can't I let the garbage collector deal with it?

Determinism.

With Rust lifetimes, you can statically prove when resources will be released. Garbage collectors provide no such guarantees. It has been shown that garbage-collected languages have a space-performance tradeoff: you need five times as much RAM to achieve the same performance, even with a "good" GC, as the same program with explicit memory management:

https://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf

replies(1): >>44020196 #
3. treyd ◴[] No.44017830[source]
You need lifetimes in order to make the affine types ergonomic to use through borrowings and aliasing mechanics. You want the affine types to prove all kinds of things about resource management, beyond just freeing allocations, which we generally call RAII. You model file and network handles as RAII, mutex locks as RAII.

Other languages use constructs like context managers or try-with-resources to capture this, but these constructs are very limited and make it very hard or impossible for these resource types to be put into a container and passed between threads. In Rust this is trivial and actually just works.

Garbage collectors usually give much weaker guarantees about when objects are freed, so destructors (which are sometimes not even available, like in JS) might only be called much later. You can't rely on a GC to unlock a muted for you. But in Rust it happens when the guard is dropped, always, immediately after it's last needed.

replies(1): >>44024056 #
4. int_19h ◴[] No.44020196[source]
That's a paper from 20 years ago. GCs have improved since then.
5. bsaul ◴[] No.44024056[source]
Since you're mentionning it : i was surprised to find no golang "context" equivalent in rust's axum. How do you manage cancelling a long-running operation triggered inside an http request handler when the connection closes ? is it via RAII ?
replies(1): >>44024526 #
6. treyd ◴[] No.44024526{3}[source]
Yeah due to the design rule that "futures do nothing unless polled", it's enough to simply drop them and it cancels the whole tree of work. That doesn't necessarily cancel other tasks that were spawned that the future might have been waiting on. That's really easy to build if it's needed, since we do have RAII. This is part of why Rust's futures compose really well in ways that goroutines just do not and JS promises struggle with.
replies(1): >>44027692 #
7. bsaul ◴[] No.44027692{4}[source]
Never thought of it like that. Super interesting, thanks.

Edit: isn't that the case for all "async" systems, in every language ?