HackerTrans
TopNewTrendsCommentsPastAskShowJobs

moldavi

no profile record

comments

moldavi
·2 года назад·discuss
Do Apple's chips (M1 etc) change this at all, since they share memory with the GPU?
moldavi
·4 года назад·discuss
You know nothing of what I'm programming. You don't know when, whether, or how my program accesses or deletes data. You don't know what domain I'm in, whether I'm on a team, or what our priorities must be.

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
·4 года назад·discuss
GP was confused about why the doubly linked list case was so important, so I enlightened, it's an example of an entire class of the borrow checker's problems.

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
·4 года назад·discuss
It's not just doubly linked lists. They're just a basic example of borrow checking not being able to handle a lot of easy patterns that are perfectly safe in other languages.
moldavi
·4 года назад·discuss
I've experienced this as well. Any disagreement always comes down to "you just haven't used it enough". I let myself take that gaslighting for years before I decided to just not go to the Rust servers any more.

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
·4 года назад·discuss
Single ownership often introduces bugs of its own. In Java, I never need to create an Err if the thing my ID is "pointing" to isn't around anymore in whatever hash map the borrow checker made me store it in.

It's good in some cases, bad in others.
moldavi
·4 года назад·discuss
Pony is a great example of fearless concurrency without the borrow checker's difficulties.
moldavi
·4 года назад·discuss
That absolute claim is simply not true. That's like saying that people need to avoid shared mutability in every program, which simply doesn't make sense for a lot of programs, especially if you have a garbage collector already.

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
·4 года назад·discuss
Easier than C or C++ for sure. But I definitely wouldn't say that Rust as easy as a GC'd language like Java or Go.

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
·4 года назад·discuss
Can we please not do this?

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
·4 года назад·discuss
I'm sometimes a bit confused when people say that Rust has less cognitive load. I assume that's compared to something like C or C++, right?

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
·4 года назад·discuss
Rust will never be used as widely as GC'd languages like Java, Go, C#, etc.

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
·4 года назад·discuss
I've seen both sides of this, as a Rust user and as a Go user.

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
·4 года назад·discuss
For a single player turn-based game, I'm not so sure the tradeoff is as obvious as everyone says, after coding one in C++ and another in 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
·4 года назад·discuss
Saying it's "idiomatic" isn't very actionable advice for people, the average programmer hears that and doesn't really know when to use Rc over other approaches. I also wouldn't say to always go with the most ergonomic approach, that approach can lead to code that is even slower than other languages.

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
·4 года назад·discuss
That's where the discipline comes in: one has to know when it's okay to use the simpler approach (indices into a Vec), and when it's better to use Arcs such as to prevent privacy problems.
moldavi
·4 года назад·discuss
In Rust, people tend to go for the easiest solution that works within the borrow checker, and not workarounds like Rc or Arc. Otherwise, the performance hit means there's little reason to use Rust over much easier languages.
moldavi
·4 года назад·discuss
That's why I said one should have the discipline and practices in place to avoid this bug.

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
·4 года назад·discuss
That's why I mentioned one needs to have discipline, to not use that particular solution.

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
·4 года назад·discuss
In fact, in the pursuit of eliminating memory-safety and security bugs, Rust can sometimes makes some privacy bugs more likely.

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.