Live data from Hacker News

Practical Go: Real-world advice for writing maintainable Go programs

dave.cheney.net

71–80 of 237 posts

Re: Practical Go: Real-world advice for writing maintainable Go programs

#71
About half-way through and I think this is a great article, in particular the quotes and I also agree that the first 4 sections are generally applicable.

One thing I disagree with is the remark about having fewer, big packages. Though conceptually I agree that avoiding having too many public APIs that aren't widely used makes sense, in practice--at least on the types of projects I tend to work on--I find that directing people to split things into a few packages forces them to think about a decoupled design with good APIs between the components. This could certainly be done with discipline inside a single package, but unless everyone working on the codebase is very diligent about this it's easy for abstraction leaks to creep in.

Ultimately it's a judgment call, but I think an earlier paragraph (copied below) is far more important than optimizing on having fewer packages or fewer exported types and functions, especially (as is also pointed out in the doc) you can use `internal` subdirectories to make APIs project-private if you are writing a library that is consumed by other projects, as opposed a service.

> A good Go package should strive to have a low degree of source level coupling such that, as the project grows, changes to one package do not cascade across the code-base. These stop-the-world refactorings place a hard limit on the rate of change in a code base and thus the productivity of the members working in that code-base.

Re: Practical Go: Real-world advice for writing maintainable Go programs

#72

Love Mr. Cheney, hate stuff like this. Someone who has put the hours in will probably stray from all of this advice, and still end up with something beautiful. Meanwhile, for all of the other schmoes who haven't put the hours in, this is just more fuel for screeching about how this name isn't right or that comment is too long. Dijkstra said GOTO was bad, and now we have callback hell and 10-layer inheritance hierarch…

If you're writing the kind of thing where you need callbacks, GOTO isn't going to make it more clear what's going on...

Re: Practical Go: Real-world advice for writing maintainable Go programs

#73
post #46

> 2.1. Choose identifiers for clarity, not brevity This is a real problem in Go these days, people use one and two letter vars quite a bit which makes reading code you’re not familiar with practically impossible. On one project we simply switched to semi-java length like names since our customers couldn’t read the code.

Since when are variables names a language issue? There is no such thing as "Java length like names", or whatever. There are good practices and bad practices and they are universal.

Good naming is almost all that matters infact, that’s how you express your intentions to the reader. You can dispense with all other constructs in a programming language as long as it’s turing complete, but no one would be able to understand your program then.

Re: Practical Go: Real-world advice for writing maintainable Go programs

#74
post #42

Earlier quoted context omitted.

And this is worse advice: > Functions should do one thing only. ... In addition to be easier to comprehend, smaller functions are easier to test in isolation, and now you’ve isolated the orthogonal code into its own function, its name may be all the documentation required. Using single-caller functions as a substitute for comments makes the workings of a specific operation much harder to follow, as you have to jump a…

> A long function is easier to understand than an exploded one. This is a pretty controversial position, and quite situational in my opinion. I absolutely agree that having to hop all over the source to understand something is frustrating, but that doesn't mean that very long functions are the right solution. Some combination of reasonably named helper methods and a function flow that makes the logic easy to parse sh…

See: http://number-none.com/blow/john_carmack_on_inlined_code.htm...

Re: Practical Go: Real-world advice for writing maintainable Go programs

#75
post #29

Earlier quoted context omitted.

Disagree hard on Go vs Python. Python is my day job, but documentation is rough . You're likely not going to get documentation for all the types, and if you do it's usually in one giant page and you can't tell which class's `__str__()` docstring you're looking at. Often you'll have a method with some terse description for parameters that don't completely describe the types accepted for a parameter. Most of this stuff…

> Godoc also has really nice support for executable examples, and examples run as part of the test suite so you know they're up to date. Ah yes, the nice godoc feature which only got added to the python stdlib in checks note 2001.

I didn't mean to convey that it didn't exist in Python; I was just remarking that it was a nice feature. No need for the snark.

Re: Practical Go: Real-world advice for writing maintainable Go programs

#76
post #71

About half-way through and I think this is a great article, in particular the quotes and I also agree that the first 4 sections are generally applicable. One thing I disagree with is the remark about having fewer, big packages. Though conceptually I agree that avoiding having too many public APIs that aren't widely used makes sense, in practice --at least on the types of projects I tend to work on--I find that direct…

I agree with you. I like the way packages are isolated from each other, meaning that to understand a package it is usually by definition a good start to simply read what is there. Smaller packages mean more bite-sized chunks of the program. And I think the discipline of slicing up your program this way is very, very good for the design, and often makes the tests easier to write to by significantly shrinking the surface of what your tests have to "fake" in order to test your code. I think it's just a whole heapin' helpin' o' benefits.

However, I feel myself to be in the minority on this one. To which I basically shrug and write my code with lots of relatively small packages. It really only affects code you're working on, or that your team is working on. Things you pull in as libraries and have no direct interaction with don't matter too much on this front.

Re: Practical Go: Real-world advice for writing maintainable Go programs

#77
post #29

Earlier quoted context omitted.

I guess it's hard to get around to the advanced features when so few people even bother to take advantage of the basic ones. Documentation for most Go libraries I've come across has been pathetic compared to similar things in Python or PHP. edit: Compare to something like Racket: https://docs.racket-lang.org/plot/intro.html?q=graph#%28part...

Disagree hard on Go vs Python. Python is my day job, but documentation is rough . You're likely not going to get documentation for all the types, and if you do it's usually in one giant page and you can't tell which class's `__str__()` docstring you're looking at. Often you'll have a method with some terse description for parameters that don't completely describe the types accepted for a parameter. Most of this stuff…

You absolutely want to add documentation linters to your build process as early in any project as you can. Just requiring that something be in the function docstring is usually enough to get people to put at least a minimal amount of description there.

Re: Practical Go: Real-world advice for writing maintainable Go programs

#78

This is so fortuitous as I started writing my first real Golang service and as a python dev I have no idea what I am doing. But one refreshing thing is how opinionated the language and the frameworks are refreshing as there’s only one acceptable way to do many things.

I agree so much with this. I recently attended a Golang meet up and since I was one of the few who had been using the language regularly for over 2 years now i was asked to let the newcomers know my favorite "feature". I replied with the same point you make above and was met with a look of refreshment on people's faces.

Go lets you write One True Code for the most part.

Re: Practical Go: Real-world advice for writing maintainable Go programs

#79

Earlier quoted context omitted.

I took issue with this because it's a conventional wisdom, and does a fair bit of damage. Single-caller functions attract other callers over time, gain backwards-incompatible features, and result in regressions.

This is one reason I like nested functions. They’re not available to the surrounding scope so they don’t succumb to these weaknesses, while also allowing you to organize your very long function internally by task. I use ‘em in Python all the time. It’s a bummer that more languages don’t support them, though you can get there with lambdas too, sometimes at the cost of more syntax.

Yeah, agreed. I do this in Rust a lot too, and I picked it up while writing a lot of Python.

Re: Practical Go: Real-world advice for writing maintainable Go programs

#80

Earlier quoted context omitted.

This is one reason I like nested functions. They’re not available to the surrounding scope so they don’t succumb to these weaknesses, while also allowing you to organize your very long function internally by task. I use ‘em in Python all the time. It’s a bummer that more languages don’t support them, though you can get there with lambdas too, sometimes at the cost of more syntax.

Go has closure functions; great feature. One of the (few) things I like about Javascript is the ability to define a closure anywhere in the containing function, so it appears in the order of operations: function f() { setTimeout(fDing, 2000); g(); function fDing() { ... } }

Disclaimer: I have no Golang programming experience.

I am curious with this approach though...you're nesting behavior and/or logic, doesn't this further obscure the meaning of the code and contribute more to the need to jump around the source in order to figure it out?

Post reply on HN