4 ms·
> and refactoring hard The opposite, it makes refactoring really easy, because it's so hard to screw up mechanical changes. The memory management aspect of re
by gpm 6y ago
> and refactoring hard
The opposite, it makes refactoring really easy, because it's so hard to screw up mechanical changes.
The memory management aspect of refactoring is slightly more tedius in rust (compared to go), because you have to update lifetime annotations sometimes. This is a mechanical process and not hard. The trade off is that the existence of lifetimes and ownerships means that many of the rest of refactoring tasks (getting locks right, not introducing data races, making sure you're not doing something dumb like accessing a freed fd, etc) are much simpler.
Rust is also better than go at refactoring because go's ducktyping (and reflection) means that there is frequently action at a distance that is hard to track down. Changing the name of a field of a struct can change behavior in another file that never mentions the field by name.
Go is in the middle of adding generics to the language, I don't think Rust has made a change of that magnitude since it hit 1.0...
- rowchain 6y ago> The memory management aspect of refactoring is slightly more tedius in rust (compared to go), because you have to update lifetime annotations sometimes. It is much more complicated. You sometimes have to implement clone, pin/project, box etc to satisfy new trait bounds for example. Also, build times can make refactoring and iterating really painful. I like and use both languages; I think they are complimentary, and I think things need to be weighted more honestly than what I see in this discussion.
- titzer 6y agoI am by no means a Golang developer, so don't construe my OP to be a particular endorsement of Go. But after 25 years writing C/C++, Java, Javascript, and working on language implementations, garbage collectors, JITs, VMs--what most people consider "system software"--I feel strongly that requiring programmers to reason about ownership for memory management is a complete waste of everyone's time. It's more mental load than programmers should not be burdened with, no matter how good the tools for it are. The performance costs of GC are routinely overstated by C/C++/Rust advocates to the point that GC implementation experts have pretty much become cut off from the conversation. No one really measures properly, anyway. My honest opinion is that it is 2021 and it's about time we let computers manage memory already. Rust can have their ownership for race conditions if they want, but I am so tired of being gaslighted about how important it is that I be hounded to track every solitary byte of memory when I am busy thinking about more important things.
- steveklabnik 6y agoThis is why this subject is hard to talk about. I fully agree that humans shouldn't have to care about memory management! That's why Rust is so important: the compiler thinks about it so that I don't have to. People can even agree on the main points and completely disagree on the conclusions.
- titzer 6y agoUnfortunately the space is littered with confounding variables. For example, just measuring the impact of GC overhead is bound to be tricky, because a trashy program (one that allocates a lot of garbage) is going to make GC look bad in comparison to a program that is careful to reuse data structures. And that's mostly because of the second-order effects of the memory hierarchy, and not so much about the raw cost of allocation or deallocation! A lot of language library choices contribute to trashiness; e.g. in Java it is very difficult to avoid making lots garbage if you use essentially any of the JDK. You can't even parse integers or strings effectively without multiple copies. I really don't know how Go's libraries look in that regard, but the truism generally holds that the more bullet-proof you try to make APIs, the more defensive copies you end up making. Is the antidote to those inefficiencies an ownership model that forces you to reason about mutability? I don't know. I kind of think no, primarily that it is a performance consideration that infects the API and spreads everywhere; it's a distraction. Is it instead to have all immutable data structures and an insanely smart compiler that replaces copying with in-place mutation, so that pure functional languages compete with highly tuned, pervasively mutable code? I kind of also think, no. And primarily that's because performance cliffs get worse and harder to predict, the smarter your compiler is. The mutability/ownership question is confounded with allocation and deallocation. The latter really should never be on any programmer's mind, IMHO. In Rust, it seems there isn't much support for decoupling the two, e.g. by having an automatic garbage collector. That's also an unfortunate reality forced on language implementers by the fact that LLVM has steadfastly refused to support stackmaps as a first class concept for more than 15 years. Many, many projects have died because of LLVM's stackmap support being lacking or broken. That's unfortunate because precise stackmaps are a key enabler for many GC techniques, and without them, you end up with some form of conservatism that make certain optimizations impossible, and forces a particular design for nurseries.
- seer 6y ago> Changing the name of a field of a struct can change behavior in another file that never mentions the field by name. I don’t code in go so this looked surprising to me. TypeScript has a similar feature regarding types, and it will tell you if you change a field in a record, and that record is actually used in a place where another record with the same fields is asked for. Kind of surprised go has this problem.
- gpm 6y agoDifference cause of a similar issue. A fair bit of go code relies on reflection to list the fields of a struct and decide what to do, so e.g. if you change the name of a field in a struct and you happened to be serializing the struct somewhere else the serialization will change even though nothing near to the name change suggested that the struct was ever being serialized in the first place. Apart from serialization I've also seen this with ORMs, and some of internal code for metrics. I imagine there are other cases too... but while I currently work in go I'm not really that much of an expert in the language.