Hacker News new | ask | show | jobs
by wyldfire 1274 days ago
> Has anybody had the opportunity to compare the costs and benefits?

Heap allocators are very significant cost over stack. Nim's designed for different use cases. Rust statically checks memory usage, and provides Arc for use cases that can only be modeled dynamically.

4 comments

ARC in Nim does not mean the same thing as in Rust. I'm still not fully up to speed on ARC/ORC nor went very far on Rust, so I might be wrong here, but from what I understand:

In Nim using ARC/ORC the compiler statically checks the memory usage, possibly helped by lent and sink annotations (similar to borrow and lifetime annotations in Rust, but not as powerful yet) and for what can't be proved statically it adds reference counting. And even under ARC you will probably be using stack allocations a lot in Nim.

I think the main difference between Rust and Nim approaches to memory management is opt-in vs opt-out. In Rust you are forced from the start to think about it and be more explicit about it, while in Nim the lifetime annotations are more like optional optimizations that may be added gradually to help the compiler, that might otherwise be adding reference counting and copies behind your back to maintain correctness.

For some use cases, being forced from the start to think in a lower level of abstraction is helpful and makes the performance more predictable and transparent. People still use C partially because of that. But I like Nim's approach where I can use it as productively as an scripting language avoiding premature optimization, but can easily delve as low level as I want to write a keyboard firmware or GBA game.

The name is confusing, but Nim's Arc is not the same as Rust's: https://nim-lang.org/blog/2020/10/15/introduction-to-arc-orc.... Rust (and apparently Swift) uses Arc to refer to atomic reference counting, whereas Nim's means automatic. There's still overhead, but it would be more comparable to Rust's Rc, I believe.
Swift uses ARC to mean automatic, and its use comes from Objective-C's ARC.
Huh, the Nim blog post appears to be wrong, then, or I misunderstood it.
Nim has good stack value support too. Heap vs stack is just treated as more an optimization thing. Rust's borrow checker is most useful for heap memory, not stack.

For stack based values Nim's 'var' and 'openArray[T]' are roughly equivalent to simple implicit lifetimes. I don't know the proper parlance vs more complicated lifetime situations like "capturing" a lifetime.

Its not too different to C++ references either. Sounds like D will also check for similar "lifetime" violations soon as well.

The real difference is heap memory. There Rust's lifetimes allow you to give ownership away. Nim's var parameters can't do that, but instead it gives you fast and cheap non-atomic ref counting. Rusts way does encourage slightly faster code on average at the expense of more effort on programmers.

Whether Rust or Nim, allocations are expensive. Though in my experience Nim's allocator is amazing. It can sometimes be faster to use ref's than stack values.

Rc and Arc require a general heap in Rust (pending support for local allocators, or Storages or whatever they end up with).