3 ms·
I don’t think any language can prevent poor structure or poor design. And it certainly can’t prevent debt like parameter inflation (rather than refactoring laye
by amscanne 4y ago
I don’t think any language can prevent poor structure or poor design. And it certainly can’t prevent debt like parameter inflation (rather than refactoring layers, using encapsulation, etc.).
I think that the simplicity and explicitness actually help to make these kinds of flaws more obvious. This is probably better than hiding poor structure with clever language features. (I’m not saying that those features are always bad — Go is certainly missing some upsides from these — but they can also be used to mask deeper issues.)
In other words, Go’s simple language won’t stop you from seeing bad code, but hopefully means it’s easier to see and understand structure (and improve it?). Maybe the awfulness of a codebase is more a consequence of the team culture and history, but the language can influence how difficult it is to see the problems. I certainly think this would apply to C/C++ (with C being less powerful and harder to hide).
- jmaker 4y agoI think some languages are better suited than others for certain styles of code and specific kinds of software. Go’s syntax might appear simple as opposed to Scala say, but Go’s semantics have enough idiosyncrasies to seed a lot of bugs which an inexperienced gopher wouldn’t manage to detect even after all linters having been applied and the compiler being satisfied. Considering older languages such as C++ and Java, the latter has several frameworks for web apps where a lot of complexity is opaque to the user as long as the user sticks to the defaults. For C++ there are few. In either case, over time certain patterns of design emerge. Typical concepts such as dependency injection makes sense with some semantics but but less so with others, e.g., with Scala’s implicits, while still being applicable in another style of Scala. With Go, one can alter receivers on a per-package base. The complexity never goes away, it’s always somewhere and there’s always some cost to managing it. With Spring, you pay with performance as long as you stick to the defaults and they don’t match exactly your model of execution. With Scala and Haskell, it’s on the type level and mostly implicit but the compiler has got more skin in the game and gets to help you a lot—you sort of ask the compiler to assist you more the more explicit you are about your types. With Go, the complexity is scattered and smeared across your code structure. And it’s on you to properly chase it. With generics it’s a bit simpler now. And abstractions are a boon in the hands of an experienced developer. And sometimes they really should be discovered and not imposed—depends on whether the problem is formulated beforehand or in the process of an agile cycle.
- amscanne 4y agoI think you’re painting with too broad a brush. Of course Go has some idiosyncrasies, but I think the number is fairly low because of the relatively small number of language features. With frameworks you’re still making a bunch of parts implicit for more expressivity, which is not something Go favors. Even the testing has a core philosophy of no magic assertions or frameworks, just regular code. There are indeed trade-offs in terms of where complexity lives, but I would not say that with Go it is smeared across the code structure. That depends on design. However, some complexity is more explicit and apparent in the code itself, which I believe the language philosophy holds as a good thing (hidden complexity is worse than complexity). For example, the classic “if err := …; err != nil” is the complexity of error handling in your face. There’s no lovely “!” operator or exceptions to hide that away and produce a beautiful, minimal function. But exceptions are an obvious example of the danger of these kinds of features; they will hide all kinds of unexpected code paths and behaviors. The Go programmer is forced to deal with these things in a “dumb” way, but I think this ends up being beneficial in most cases.