4 ms·
> Often safety and performance are characterized as a set of zero sum tradeoffs, yet often it's possible to find better tradeoffs who's holistic properties impr
by verdagon 3y ago
> Often safety and performance are characterized as a set of zero sum tradeoffs, yet often it's possible to find better tradeoffs who's holistic properties improve upon a previously seen "either or".
There is truth in this, but I'm not sure whether the reader can/should extrapolate this to larger situations (not that the author implied we should, but it was my first interpretation).
We know that in certain situations, borrow checking works really well and allows us to guarantee safety with minimal friction and no overhead.
But there are other cases where safety and performance _are_ in contention, and we must choose one or the other. Anyone who has been forced to satisfy the borrow checker by using a .clone(), using Rc, or refactoring objects into a hash map and referred to them by an ID (that must be hashed to exchange with a reference), has felt this contention. In https://verdagon.dev/blog/myth-zero-overhead-memory-safety https://verdagon.dev/blog/myth-zero-overhead-memory-safety, I concluded that there's no general approach that always has zero overhead, at least not yet.
So perhaps the best interpretation from this study is that often, for small enough programs/areas, there is no conflict between safety and performance.
For larger programs with more complex requirements and data interrelationships, the question becomes much more interesting.
> I see no reason why a straight port from Rust to C++ wouldn't have been possible while satisfying their requirements.
Like the author, I also don't see a reason for this, but I've never tried myself. I've always thought that with the restrict keyword, one could make any C++ as performant as any Rust code. Perhaps something else got in the way there.
- wredue 3y agoSorry, but you are just assuming that the borrow checker is an authority of safety, when, even stated by rust lang developers, it is not. The borrow checker is known to be far in to “overly cautious” territory.
- verdagon 3y agoI made no assumption like that, though do let me know if I've said something that could be interpreted that way. Rather, I think that the static analysis we see in today's languages just isn't powerful/flexible enough to reason about safety in a lot of the patterns that we know are safe. I'm also uncertain if it can _ever_ catch up to what we know to be safe, but I wouldn't be surprised if we get there in a few hundred years. For example, borrow checking is a step forward and can guarantee safety, but does nothing about the other half of correctness, specifically liveness. [0] Linear types (like in Austral [1] and Vale's higher RAII [2]) can help guarantee liveness, but we still have further to go. Both are based on single-ownership (in the C++ sense) like Rust, which introduces errors that e.g. Haskell would not. But even Haskell (and LiquidHaskell which has linear types) don't go far enough; Coq goes even further. So yes, like you say, we have a long way to go w.r.t. correctness, even past the borrow checker though it is a big step forward. To my original point though, even all of these tools put together will put restrictions on a program such that it sometimes won't be allowed to take the most optimal approach. Perhaps someday we'll get there! [0] https://en.wikipedia.org/wiki/Safety_and_liveness_properties https://en.wikipedia.org/wiki/Safety_and_liveness_properties [1] https://austral-lang.org/linear-types https://austral-lang.org/linear-types [2] https://verdagon.dev/blog/higher-raii-7drl https://verdagon.dev/blog/higher-raii-7drl
- wredue 3y ago> But there are other cases where safety and performance _are_ in contention, and we must choose one or the other. Anyone who has been forced to satisfy the borrow checker by using a .clone(), using Rc, or refactoring objects into a hash map and referred to them by an ID (that must be hashed to exchange with a reference), has felt this contention. Yes. You literally did assume that the borrow checker is an authority, as seen here. To be frank with you, given that zig is 95% of the way there, I feel that you are “diving off the deep end” when stating things like “Haskell doesn’t go far enough”. Haskell typing system is a nice experiment, but I don’t believe to be good in any capacity, let alone “not going far enough”. Haskell, in my opinion, a great case of “solving a problem before even asking what the problem really is”.
- _a_a_a_ 3y agoSo what problem do you think Haskell thinks it's solving?
- wredue 3y agoI haven’t the foggiest clue what problem Haskell is solving, because as far as I can tell, it doesn’t solve any problem particularly well. Hence “solving the problem before even asking what their problem actually is”.
- _a_a_a_ 3y ago"Designed for teaching, research, and industrial applications" - from wikipedia (2nd sentence) Seems to have done pretty damn well IMO. Not that I've used it for 25 years, but I liked it and it introduced me to FP which totally changed how I thought of programming. I guess we have to differ on this.
- wredue 3y agoYes. It changed how you thought about programming *for the worse*. Whereas I believe that concepts are tools for programmers to reach for when appropriate, functional programmers believe concepts are rules and reaching for them should be mandatory, no matter how much bullshit they force you to add for no reason other than you accepted from the get go that, for example, immutability should be mandatory. This is a massive fundamental problem with Haskell and all language that take hardline stances on things that are better left to the users. In this regard, I’d say it’s a complete failure. It’s horrible for teaching. You need to know more than you need to know for Java just to use it. It’s horrible for research. It has hardline fundamental stances that rejects exploration, and therefor is research averse. It is horrible for industrial applications as there are massive ranges of industry that simply cannot give to the whims of Haskell for one reason or another, but probably multiple reasons cause Haskell is terrible.
- deleted 3y ago[deleted]
- Guvante 3y agoHonestly I think unsafe Rust is the solve here. Often you have an isolated data structure that is relatively simple that needs to break the borrow checker rules (without invoking UB such as multiple mutable references). An often times a safe API can be written on top of that. However the current state of this is absolutely terrible. A lot of work needs to be done to improve the development experience with this model if it is to be used effectively in this way.