3 ms·
> encourages breaking large systems into small services That's as much of a curse as it is a blessing. To some extent, small services are handy for dev/ops typ
by waps 12y ago
> encourages breaking large systems into small services
That's as much of a curse as it is a blessing. To some extent, small services are handy for dev/ops type folks, as they can quickly see which specific part of an application is misbehaving with memory or cpu or diskspace, so they like it.
But small services means that you lock down the interface between parts of the system by using another language to specify the communications protocol (e.g. protobuf, json, ...) and 2 different codebases have to understand it. And even if you manage to get the code to change, now you have the problem of migrating the running program.
In other words, the interface is now set in stone. Nobody will ever touch it again. This is exactly what you do not want to happen. Small services are the enemy of large, flexible programs.
Contrast this to Java/C# (and, somewhat less perfectly, C++) and their refactoring tools. What a difference. Changing an interface is something that is mainly done by computer code, not by a programmer, and all parts are modified and all problems identified.
There are points where this is not a problem, like a file system interface, or a socket interface, that sort of thing (and even there you may change your mind ...). Places where flexibility is not needed or wanted (I would argue, looking at linux file systems, that the POSIX API is not, in fact, a good API for quite a few file systems, but looking at the kernel I can see why this is not going to change. Of course, half the distributed file systems are user space libraries, partly for this reason). This is exactly the sort of thing C programmers deal with.
- NateDad 12y agoOne of go's strengths is how easy it is to refactor. Implicit interfaces means that you can change a function to take an interface, and the caller who is passing in a concrete type doesn't have to get updated at all. also, there's a relatively recent tool created called gorename that does 100% type-safe renaming. Plus there's been gofmt and gofix for forever which you can use to automatically rewrite your code. Finally, because almost all go code is formatted with gofmt, you can often do simple find and replace changes because all the code is completely regular.
- waps 12y ago> One of go's strengths is how easy it is to refactor Give me a minute to collect my jaw of the floor here. Nope ... need some more time. Unless you mean in the same way as C and pascal are easy to refactor, I disagree in the strongest possible way. I may conceed to a very limited extent. While Go and it's tools don't allow refactoring, due the static nature of Go, it's actually possible, through careful design and constantly putting extra effort in, to make sure that it's reasonably easy to refactor. As long as you stay away from using interfaces, use long and unique enough names for your variables, make sure no variable names are substrings of other variable names, have a convention for polymorphic method names (ie. Matrix.MakeWithFloatArray(), Matrix.MakeWithIntArray(), Matrix.MakeWithZeroes(), ...), ... > Implicit interfaces means that you can change a function to take an interface, and the caller who is passing in a concrete type doesn't have to get updated at all. Yes because that's what refactoring is ... what you're showing here is called "polymorphism", and Go "doesn't support it" (except when it does, like as you point out here, in interfaces, oh and in range, make, new, append, close, copy, delete, imag, len, print, println, real, go, defer, most of which are also generic and polymorphic in really, really bad ways (some have completely unrelated and surprising behavior when passing different types to them), and I doubt I've got all of them). > also, there's a relatively recent tool created called gorename that does 100% type-safe renaming. > Plus there's been gofmt and gofix for forever which you can use to automatically rewrite your code. >Finally, because almost all go code is formatted with gofmt, you can often do simple find and replace changes because all the code is completely regular. I have tried that tool. It only does a single file. Again that makes it not refactoring. Just so we're clear. Here's the definition of refactoring : Code refactoring is the process of restructuring existing computer code – changing the factoring – without changing its external behavior. Which is not what those tools do. Change the name of a method ... boom 5 objects don't satisfy the interface they did 5 seconds ago anymore. Change the name of an interface ... doesn't change in all other parts of the code. Change an exported variable ... everything fails to compile. Next major point of criticism of the go tools. When do you want to do refactoring ? Well, during development. Of course in order to refactor during development, when 2-3 of your program's files don't compile, you obviously cannot use a normal compiler to refactor, since it won't understand the program. While this is not technically part of the definition, it frustrated me to no end the first, and last, time I used gofix to attempt to refactor something. Me and vim are faster at refactoring a 10000 line Go codebases than gofix + cleaning up after it is. Gofix knows a cute trick with symbol tables that is 1% complete (because making it functional will require a full rework of the Go compiler), which is not refactoring (since it doesn't look at the full source tree), and it will require a rework of Go itself (I'm not yet positive, but I think that because Go works with implicit interfaces, it is not actually possible to refactor anything related to object methods or interfaces correctly).