moldavi | 1 year ago | on: Understanding SIMD: Infinite complexity of trivial problems
moldavi's comments
moldavi | 3 years ago | on: Choosing Nim out of a crowded market for systems programming languages
And yet, you proclaim that your approach is how I should always do it in any language, in any situation.
It strikes me as particularly convenient, seeing as that's the only approach that the borrow checker can reason about.
To make it more concrete: if we apply your solution everywhere we run into this problem with the borrow checker, it can flatten a lot of our program's (non-temporary) state into basically relational tables. Sometimes that's okay, but for a lot of situations it can be bad for encapsulation, velocity, and modularity.
moldavi | 3 years ago | on: Choosing Nim out of a crowded market for systems programming languages
Your response isn't really relevant in that context, and instead escalates to a much larger debate, so best I not engage. Appreciate the thought though =)
moldavi | 3 years ago | on: Choosing Nim out of a crowded market for systems programming languages
moldavi | 3 years ago | on: Choosing Nim out of a crowded market for systems programming languages
And then when you question any of the classic Rust axioms (such as safety or speed being only desirable rather than an absolute commandment) a lot of them tend to get rather hostile. It's not a pleasant crowd if you don't think 100% like they do.
moldavi | 3 years ago | on: Choosing Nim out of a crowded market for systems programming languages
It's good in some cases, bad in others.
moldavi | 3 years ago | on: Choosing Nim out of a crowded market for systems programming languages
moldavi | 3 years ago | on: Choosing Nim out of a crowded market for systems programming languages
It's only a useful tool that has some nice qualities in some settings. It's not some underlying truth of the cosmos, it's just a situationally useful way to do things.
moldavi | 3 years ago | on: Choosing Nim out of a crowded market for systems programming languages
They have strictly less constraints to deal with, they can let you use the simplest pattern for the situation, and (in my experience) they have less superfluous refactoring sessions due to the overly conservative nature of the borrow checker. I like how Matt Welsh put it in https://mdwdotla.medium.com/using-rust-at-a-startup-a-cautio...:
> What really bites is when you need to change the type signature of a load-bearing interface and find yourself spending hours changing every place where the type is used only to see if your initial stab at something is feasible. And then redoing all of that work when you realize you need to change it again.
Perhaps you're instead speaking of a specific situation or kind of program where the borrow checker happens to be no harder than any other language?
moldavi | 3 years ago | on: Choosing Nim out of a crowded market for systems programming languages
It's fine to give a different viewpoint, but it's surprisingly common that whenever someone says anything bad about Rust, a Rust user comes in to say that they just haven't used it enough.
It's like saying "If you don't like my favorite movie, you just haven't watched it enough."
moldavi | 3 years ago | on: Choosing Nim out of a crowded market for systems programming languages
I've used Rust and (imperative-style) Scala a lot, and I have to say, Scala is way easier since it doesn't have to deal with the borrow checker, but it still has an amazing type system.
Nim is statically typed and has algebraic data types, so I imagine it's also as easy as Scala, easier than Rust.
moldavi | 3 years ago | on: Carefully exploring Rust as a Python developer
It's incredibly well-designed, but you can't design away the inherent complexity of writing safe, secure, fast code. There's no way to make that easy. It will always take a lot of passion or training to really master it. (Yes, I know that some of us here "had an easy time" and it "only took a few weeks", I'm referring to the average person.)
And you know what, that's okay. There are lots of industries where only the most hardcore of programmers use the professional-grade tools. There's nothing wrong with that.
Everyone else will probably continue to use tools like Java, Python, etc. because for most situations, they can get the job done with less training, which means less spent on developer salaries, which is most often more than server costs anyway.
I think the best we can hope for is that Rust is taught in university, like how other industries teach usage of their own professional-grade tools. But even that won't mean that most programmers use Rust, I think.
moldavi | 3 years ago | on: “Rust is safe” is not some kind of absolute guarantee of code safety
Rust users are generally friendly to one another, and to people who are interested in Rust. Hoever, some Rust users are toxic when talking to people outside the community or to people who disagree.
That's why a lot of us (in the Rust community) don't notice it; we spend most of the time inside our own community talking to each other and being friendly to each other.
This is a trait common to any bubble or insular community whether it be about politics, religion, economics, or whatever. It's fairly easy to recognize once you get in the habit of dis-identifying with your own side.
There's also a phenomenon in human psychology where we tend to forgive "our side's" misbehavior, presumably because it's in service to a higher ideal and therefore forgivable. It's the difference between "passionately spreading the good word" and "aggressive evangelism", two views of the same action. After learning about this I've even seen it in myself, though hopefully I've learned to counteract it a bit.
Note that this isn't unique to Rust, other languages have this too to an extent.
It's something I really hope we can leave behind, because it's hurting an otherwise beneficial message that Rust can bring a new tradeoff that is favorable for a lot of situations.
moldavi | 3 years ago | on: Unreal Rust
It's turn based, so I don't need AAA game multi-threaded performance. It's single-player, so cheating doesn't really hurt anyone.
I use sanitizers to catch memory problems, but there have only been a few of those over the years. Maybe ECS just isn't that vulnerable to memory-safety problems?
The borrow checker prevents iterator invalidation problems, but most of my functions are read-only so there's not really a chance for those anyway, or many other single-threaded race conditions for that matter.
After this long using Rust, I'm noticing more and more that the borrow checker is imposing a lot of artificial complexity, when I compare it to my C++ version. We're often told that Rust is hard because the underlying problem is hard, but I've encountered many cases where that's not true, it really is just the borrow checker. And unfortunately, most of them are problems that Polonius won't fix.
Rust has a lot of great features (enums and cargo!) but I think one should think carefully about their domain and architecture before choosing a language, lest they pay too much cost for too little benefit.
Just my two cents!
moldavi | 3 years ago | on: RustDesk – Open-source TeamViewer alternative
I would rather advise: don't reuse indices, even if that is the simplest solution that complies with the borrow checker. When one finds themselves reusing like that, that's when to turn to other more expensive approaches such as Rc.
moldavi | 3 years ago | on: RustDesk – Open-source TeamViewer alternative
moldavi | 3 years ago | on: RustDesk – Open-source TeamViewer alternative
moldavi | 3 years ago | on: RustDesk – Open-source TeamViewer alternative
I think we can do better than saying that indexes into Vecs are "non-idiomatic" in applications... such advice could remove much of Rust's performance advantage, and make folks wonder why we're not just using GC.
Perhaps we could instead say that if one finds themselves reusing slots in a Vec, they should instead use generational indices, hash maps, or Rc<RefCell<T>>, depending on their use case and what kind of performance overhead they'd prefer.
moldavi | 3 years ago | on: RustDesk – Open-source TeamViewer alternative
We agree it's not the best solution. And it's easy for us to say that now, after I've spelled out why. You'd be surprised how many people don't know that this can be a problem.
Also, it amuses me that having a simple index into a Vec would be a "convoluted solution". It's the easiest solution of all the alternatives. It can also be risky for privacy.
Compare that to a GC'd language, where the easiest solution (just hold a reference) doesn't introduce privacy risks.
moldavi | 3 years ago | on: RustDesk – Open-source TeamViewer alternative
For example, in GC'd/RC'd languages, if we have several UserAccount instances and a bunch of long-running operations on them, any particular long-running operation will just hold a reference to the UserAccount itself and modify it at will without any confusion.
In Rust, the borrow checker often doesn't let us hold a reference from a long-running operation in practice, so we work around it by putting all UserAccount instances into a Vec<UserAccount>, and have our long-running operations refer to it via an index. However, we might erase and re-use a spot in that Vec, meaning the index now refers to some other UserAccount.
If the operation uses that "dangling index", it can lead to leaking sensitive data to the wrong users, or data loss.
When using Rust, one has to use discipline to avoid this bug: use IDs into a hash map, or generational indices, or Rc<RefCell<T>>. Each has its own performance hit, but that hit can be worth it to prevent privacy bugs.
In the GC'd/RC'd language, this would still be a bug, but it wouldn't cause any mixups between different users' data.
I'm not saying we should always use GC'd or RC'd languages for privacy-sensitive purposes, but one should be aware of the particular shortcomings of their tools and have proper practices and oversight in place to mitigate them.