43:42 I think that the inout semantics that people typically have in mind are what C would call “restrict” - assume independence, and claim UB otherwise
@AbrahamsDave Жыл бұрын
To be clear, what I'm proposing there is “statically enforce independence," so UB doesn't enter into it.
@alskidan2 жыл бұрын
30:00 Reminded me I wanted to start learning Rust sometime this year. :-)
@dennis_work Жыл бұрын
Is this the Dave Abrahams who formalized exception safety?
@AbrahamsDave Жыл бұрын
The very same!
@PeregringlkАй бұрын
Reference semantics for that kind of context like sort is expressive enough. Like, if my T-shirt is dirty, I want to clean my t-shirt, not copy my t-shirt, clean the copied dirty t-shirt, and when it's clean then replace it by my original dirty one. I want to clean THIS T-SHIRT, and every single little piece of code must be as closer as possible as the way we human think. Besides, if I go to a coworker, where 99% of workers focus on practical things and consider all of this kind of very technical stuff to be in the realm of nerdy obsessions, how would you convince them to change a very expressive way of writing things to a less expressive way of writing things without any actual, practical gain? It's much cheaper keeping things as simple as possible and debug the errors when they happen, than letting complexity get out of control and adding more and more features trying to patch the consequences of complexity going out of control. Making a modification inside a comparison function is complexity going out of control and THERE is where people have to attack: by teaching people that they should not do that. In my opinion some uses of references are fine, specially functions where its only mutable reference is the first argument, because we are very used to it thanks to assignments a = b.
@AbrahamsDave22 күн бұрын
The ability to say “clean THIS T-SHIRT” is not hurt one bit by banning reference semantics. The argument is that by giving up the expression of shared mutable state you get practical gain in correctness, local reasoning, and efficiency. Also that pervasive use of references very quickly lets complexity gets out of control. The modification inside the comparison function is a particularly perverse example, but the point isn't to show that references are dangerous. The point is to show how they affect our ability to accurately and simply describe a function's contract. The more complex the accurate contract is, the harder the function is to use The kinds of things that happen with signals/slots or the observer pattern are much more typical paths to this kind of loss of control with references. I often see code that's 5-10x more complicated than it needs to be, and very difficult to debug or refactor because people are using shared_ptrs liberally. It's fine if you're not convinced, of course.
@Peregringlk21 күн бұрын
@@AbrahamsDave Thank you for your reply. As you said, the problem is getting out of control. It's like: the ability of mutating state can get out of control (in classical structured programming). Solution? Ban assignments at all (what functional languages do). That's extreme. A less extreme solution is imposing restrictions: if two functions modify a same variable, they must belong to the same class, and so you are imposing a hierarchical structure on the relationship of "modifies the same variable". That is what OOP basically does in practice. Consider the case with gotos: unrestricted gotos allowed "random arrows" between any two points of code; forbidding them stucked in people (structured programming), because now flow graphs are cognitive-friendly, but with random gotos they weren't. Also, all "fine" usages of goto (those that doesn't break the hierarchical structure) survived too, continue, break, early returns and plain gotos to jump to control error blocks in C. None of them break the hierarchical structure of the control flow because the only exit blocks, so the jumps are confined in its own box. Then of course there was people that got extreme here as well and forbid all kind of jumps: the religion of single exit points that no one follows nowadays (because the actual problem is already solved with the restrictions of unrestricted gotos). The reason that "structured relationships" don't overwhelm us, regardless of how big is the program, I think it's because the brain can apply "chunking" to it: labeling chunks of the full picture with semantic ideas that are transported like a unique thing in our brain: the label/meaning. But if there's random arrows all over the place, the chunking is gone: you cannot mentally hide away the internals of a candidate chunk if there's an arrow moving out of it to some random place of the tree/graph, and then is when the amount of things you have to think about at the same time (the complexity) exceeds your mental limits, and hence the overwhelm and mess. Structure programming? The prohibition of random arrows in the control flow graph, but not the feature (you can still jump). OOP? The prohibition of random arrows in the "mutability graph" (functions that modifies the same variable belongs to the same class), but not the feature (you can still use assign). With references is the same: wouldn't it better to impose restrictions on how/when references should be used, identifying which restrictions to impose, to avoid the relationships induced by references overwhelm our brains, instead of forbid the feature at all?
@AbrahamsDave13 күн бұрын
@@Peregringlk wrote: wouldn't it better to impose restrictions on how/when references should be used, identifying which restrictions to impose, to avoid the relationships induced by references overwhelm our brains, instead of forbid the feature at all? As I tried to make clear in the talk, you can view our system as doing exactly that. We identified the restrictions needed to keep local reasoning with references. But a reference with restrictions doesn't have all the properties of a reference anymore, so thinking of it as a reference with restrictions is like thinking of a calculator as a supercomputing cluster with restrictions. You end up with a starting mental model that's complex and have to take away features. It's simpler just to think about the values.
@olafschluter7064 ай бұрын
The remark on Rust ("has this property" (to copy collection values, when the collection is passed by value)" too" is not accurate or I misunderstood it: passing a vector (or a struct or any other collection for that matter) into a function by value in Rust involves no creation of a copy,, as it is always a move, unless the type passed by value implements the Copy trait. You can move a vector (or any other collection or struct for that matter) into a function (as a mutable value) , modify it there and return it as value, and you end up with the same object at the same address you had before, just modified. .By default, only scalar types like ints or booleans have the Copy trait and thus copy semantics for pass by value by default, and you cannot implement Copy on any foreign type (e.g. from the std library) to prank your colleagues who expect those types to have move semantics. You can do that for your own types, and pay the cost for it.
@AbrahamsDave4 ай бұрын
You're absolutely right, and I'm surprised I said that. I know better. Apologies to all.