Why, oh why, do people do this? Things that annoy me in Go code.

1,266 views
Skip to first unread message

Amnon

unread,
Dec 9, 2021, 7:10:18 AM12/9/21
to golang-nuts
1) Long functions that go on forever and contain long lambdas and 8 levels of indentation.

2) Long variable names.

3) Variable names which include the type of the variable.

4) Packages whose name contain the word '/pkg/'

5) Repos which contain the prefix go-

6) Code where almost every line prefixed by `_, _ =`
and the underscores won't go away when you wipe your screen


Robert Engels

unread,
Dec 9, 2021, 8:32:54 AM12/9/21
to Amnon, golang-nuts
5 is a best practice when you having multiple implementations written in different languages - especially when developed independently. 

On Dec 9, 2021, at 6:10 AM, Amnon <amn...@gmail.com> wrote:

1) Long functions that go on forever and contain long lambdas and 8 levels of indentation.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/d367f41a-53e8-415e-a44c-1ace051359d3n%40googlegroups.com.

Jason E. Aten

unread,
Dec 10, 2021, 2:21:56 AM12/10/21
to golang-nuts
6 is probably because of the linters that complain if you don't.

Amnon

unread,
Dec 10, 2021, 2:53:31 AM12/10/21
to golang-nuts
Indeed.

There are quite a few linters out there which object to good idiomatic code and 
which would fail the Go Standard Library.

And too many people are happy to pollute their codebase with extraneous noise,
rather than fixing the linters, or using just using high quality linters (such as go vet, and staticcheck).

On Friday, 10 December 2021 at 07:21:56 UTC Jason E. Aten wrote:
6 is probably because of the linters that complain if you don't.

Jason E. Aten

unread,
Dec 10, 2021, 8:16:02 PM12/10/21
to golang-nuts
Ya I think _, _ = blah() is ugly, but it's actually not a bad idea to communicate to the next person that you did really mean to ignore that value, error.  Otherwise they have to ask you. So I usually comment it, but the linter can't read the comment, so actually the _ is better.

Rudolf Martincsek

unread,
Jan 28, 2022, 1:12:48 PM1/28/22
to golang-nuts
> 2) Long variable names.

Where I work (not in Go), writing comments is frowned upon. That includes "docblock" style comments. If a function needs to be documented, it means the implementation is too complex and must be broken apart to reduce cyclomatic or whatever perceived complexity. Also uncle bob told us that functions should never be longer than 2-3 lines of code, so it should be enough to look at the source code to see what it does. That's the general sentiment in my team.
Comments are considered sign of "un"clean code.

So we use long variable and function names to make the code self documenting. (Hint: it doesn't)
Points 3,4,5 have similar roots, because in dynamic languages it was a trend many years ago. (ie: hungarian notation)

Tim Hardcastle

unread,
Jan 29, 2022, 6:21:19 AM1/29/22
to golang-nuts
Agree with Rudolf on point 2. Long meaningful variable/function names are good. Comments become obsolete, they become detached from their code, they're only used to explain the name of the variable once and then you're left with something than reads

// urn contains the userlist
fxn := rx (frn)

 Now that editors have autocomplete to make up for my meagre typing speed, you bet your ass I'm going to have [eg from current project] a local variable called lastTokenWasColon and a method called addWordsToParser. Because knowing exactly what they do when I need to modify or debug saves me so much time and trouble. (Perhaps this varies from person to person. If my memory is poorer than yours, it has more of an upside for me than for you.)

And is there a better solution to the problem in point 1 than to break the function down into lots of little functions with meaningful names? (If the names (and pieces) aren't meaningful you've only technically broken it down.)

David Finkel

unread,
Jan 29, 2022, 12:00:49 PM1/29/22
to Tim Hardcastle, golang-nuts
On Sat, Jan 29, 2022 at 6:21 AM Tim Hardcastle <timphar...@gmail.com> wrote:
Agree with Rudolf on point 2. Long meaningful variable/function names are good. Comments become obsolete, they become detached from their code, they're only used to explain the name of the variable once and then you're left with something than reads

// urn contains the userlist
fxn := rx (frn)

 Now that editors have autocomplete to make up for my meagre typing speed, you bet your ass I'm going to have [eg from current project] a local variable called lastTokenWasColon and a method called addWordsToParser. Because knowing exactly what they do when I need to modify or debug saves me so much time and trouble. (Perhaps this varies from person to person. If my memory is poorer than yours, it has more of an upside for me than for you.)

There's a lot of middle-ground between a three-letter variable or function-name and encoding the whole doc-comment for a function or variable in its name.
Humans only have so much working memory, once a name gets long enough we start dropping parts of the name and it tends to be stuff in the middle that gets dropped.

If you have a parser type, and a variable with that type, often, it would be better to have an addWords() method on the parser type. Then if you also need a special-case addWord() it's easy to tell what's going on.

I try to have meaningful names, but beyond some threshold, but I try to prevent things from being redundant with the types involved (the entire function signature and type of the variable).

Also, comments are not about just describing what something is. (those are the least useful types of comments) They're also quite useful for describing what's being attempted, what corner-cases are being addressed and if there's any tricky logic that needs to be handled. Additionally, IMO, just about any function or method should have a doc-comment explaining what it expects. (helpers under ~3 lines may be exempt)

And is there a better solution to the problem in point 1 than to break the function down into lots of little functions with meaningful names? (If the names (and pieces) aren't meaningful you've only technically broken it down.)

On Friday, January 28, 2022 at 10:12:48 AM UTC-8 Rudolf Martincsek wrote:
> 2) Long variable names.

Where I work (not in Go), writing comments is frowned upon. That includes "docblock" style comments. If a function needs to be documented, it means the implementation is too complex and must be broken apart to reduce cyclomatic or whatever perceived complexity. Also uncle bob told us that functions should never be longer than 2-3 lines of code, so it should be enough to look at the source code to see what it does. That's the general sentiment in my team.
Comments are considered sign of "un"clean code.

So we use long variable and function names to make the code self documenting. (Hint: it doesn't)
Points 3,4,5 have similar roots, because in dynamic languages it was a trend many years ago. (ie: hungarian notation)

On Thursday, December 9, 2021 at 2:10:18 PM UTC+2 Amnon wrote:
1) Long functions that go on forever and contain long lambdas and 8 levels of indentation.

2) Long variable names.

3) Variable names which include the type of the variable.

4) Packages whose name contain the word '/pkg/'

5) Repos which contain the prefix go-

6) Code where almost every line prefixed by `_, _ =`
and the underscores won't go away when you wipe your screen


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

Henry

unread,
Jan 30, 2022, 6:31:25 AM1/30/22
to golang-nuts
Comments are useful to communicate what is not already apparent in your code. Sometimes comments may help you find bugs in your algorithms. On the other hand, keep your comments terse and not longer than what is necessary. Respect other people's time. 

Long names are not necessarily better. It is more important to have names that communicate your intent well and those names are not necessarily long. Any name that is longer than three words is usually too long.

As for long functions, my personal rule is that when you have more than one looping construct in a function, it is time to break it down. In Go, there is only one looping construct, which is the "for" keyword.

More importantly, know your "rules" and when to break them. They are not immutable. 

Brian Candler

unread,
Jan 30, 2022, 9:24:15 AM1/30/22
to golang-nuts
On Sunday, 30 January 2022 at 11:31:25 UTC Henry wrote:
In Go, there is only one looping construct, which is the "for" keyword.

Don't forget "goto" :-)

<< ducks >>

Tim Hardcastle

unread,
Jan 30, 2022, 10:19:58 AM1/30/22
to golang-nuts
True, I don't say that meaningful names can entirely replace comments, just that comments can't replace the sort of meaningful if verbose names that OP objects to in point (1).

A lot must depend on the personal equation, how well one reads chunks of camelCase, how well one reads abbreviations, how good one's memory is, how fast one types, etc. Personally I find I just mess up less since I've learned to be more verbose.

Henry

unread,
Jan 30, 2022, 10:14:22 PM1/30/22
to golang-nuts
And there is that ... LOL. I normally ignore "goto", but yes it can be turned into a looping construct. When refactoring code that uses "goto", I would try to eliminate "goto" first. If it isn't possible, then the execution flow must be so complex that it doesn't need to be broken down further. 

Thomas Bushnell BSG

unread,
Jan 31, 2022, 4:34:47 PM1/31/22
to Rudolf Martincsek, golang-nuts
On Fri, Jan 28, 2022 at 1:12 PM Rudolf Martincsek <rud...@gmail.com> wrote:
> 2) Long variable names.

Where I work (not in Go), writing comments is frowned upon. That includes "docblock" style comments. If a function needs to be documented, it means the implementation is too complex and must be broken apart to reduce cyclomatic or whatever perceived complexity. Also uncle bob told us that functions should never be longer than 2-3 lines of code, so it should be enough to look at the source code to see what it does. That's the general sentiment in my team.
Comments are considered sign of "un"clean code.

I agree with the sentiment.

So we use long variable and function names to make the code self documenting. (Hint: it doesn't)
Points 3,4,5 have similar roots, because in dynamic languages it was a trend many years ago. (ie: hungarian notation)

If you use a long variable name for every variable then you haven't helped anything. You need to use long variable names for some variables and not others.

Using a short variable name gives the subtext "this variable is boiler-plate or not very important". This is good for method receivers, loop indexes, and so forth. Almost always a single word will do. For example:

for _, otter := ListRiverOtters("europe")

Calling this variable "otter" is great. Calling it "europeanRiverOtter" is absurd - that's already there, obviously in the code. (And if the loop is fifty lines long, then the problem isn't that the reader has forgotten what kind of otter it is - the problem is that a loop of fifty lines long is too long.)

Exported function and method names should generally read "completely", but even then, they shouldn't go repeating type names and all the rest. The standard library, as always, is a great guide. 

Rudolf Martincsek

unread,
Jan 31, 2022, 4:47:50 PM1/31/22
to golang-nuts
> Agree with Rudolf on point 2.
Then you completely misunderstood my point. Because I said exactly the opposite. If your variable names are 10-15 words long (including prepositions) then you should document what the function does.

Rudolf Martincsek

unread,
Jan 31, 2022, 5:14:42 PM1/31/22
to golang-nuts
> for _, otter := ListRiverOtters("europe")
> Calling this variable "otter" is great. Calling it "europeanRiverOtter" is absurd - that's already there, obviously in the code. 

Your "absurd" example is too charitable and naive. That's not even bad compared to what I encounter day by day. Some would write this as:

$europeanRiverOtters = $this->ottersFetcher->fetchOttersForContinent("europe");

But even this "worse" example pales in comparison to the actual code I have to deal with. To the tune of classes being called "DoSomethingForXAndYService" with methods like "getCountOfTotalX", "getAndSaveXInTable", "getXEligibleForY", "sortXByYAndZAndGroupByW" and so on. Where X, Y, Z, W are entity/model/domain_object/field names. I wish I could show examples, because you'll say that I'm exaggerating, but of course I can't.
And on top of this, english is not our mother language, but we write code in english. Reading the code becomes atrocious.

Rick

unread,
Jan 31, 2022, 7:43:44 PM1/31/22
to golang-nuts
Really? The idea that functions should never be longer than 2-3 lines is absurd. Functions should take an input, do one thing (without side-effect) and return a result. And their name should indicate what function they compute. Whether that is 2-3 lines or 20-30 lines depends on the function.

Robert Engels

unread,
Jan 31, 2022, 9:42:41 PM1/31/22
to Rick, golang-nuts
If I hired on to a company that enforced 3-4 line function calls I would be looking for a job the next day. 

On Jan 31, 2022, at 6:44 PM, Rick <thesuggested...@gmail.com> wrote:

Really? The idea that functions should never be longer than 2-3 lines is absurd. Functions should take an input, do one thing (without side-effect) and return a result. And their name should indicate what function they compute. Whether that is 2-3 lines or 20-30 lines depends on the function.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

Amnon

unread,
Feb 2, 2022, 1:51:54 AM2/2/22
to golang-nuts
Idiomatic naming in Go is one of the hardest things to communicate.
Everyone seems to bring the idioms from previous languages. Dave Cheney writes about 
"Lengthy bureaucratic names carry a low amount of signal compared to their weight on the page".
Identifiers are not sentences or stand alone stories. They are the the basic building blocks for our code.
We have all seen code infected by these names - long names leading to long lines of code,
and verbose walls of dense text, repetitive and hard to read.

I always encourage people to read https://go.dev/doc/effective_go#names
to study the Go standard library, and develop a feel of what Go code should read like.



Rudolf Martincsek

unread,
Mar 7, 2022, 3:50:21 PM3/7/22
to golang-nuts
Latest interface my colleagues wrote (it's PHP)
---
interface UnreceivedMasterOrdersInterface
{
   public function getUnreceivedByProductsWarehouseAndCompany(array $productIds, int $warehouseId, int $companyId): array;
}
---
There is interest to switch to Go for some of the stuff we write, but I decided to leave before that happens. I like programming in Go for myself, and I don't want to start hating it because of nonsense like this.

Rob Pike

unread,
Mar 7, 2022, 5:22:28 PM3/7/22
to Rudolf Martincsek, golang-nuts
It could have been

interface UnreceivedMasterOrdersInterfaceThatCanBeUsedToCallGetUnreceivedByProductsWarehouseAndCompany

Seriously, though, your example isn't even on the same planet as some
of the examples I've seen. (Neither is my parody.)

Sympathies.

-rob
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/00dec58d-421a-4b86-9c15-6533fc648974n%40googlegroups.com.

Bakul Shah

unread,
Mar 7, 2022, 6:08:09 PM3/7/22
to golang-nuts

Henry

unread,
Mar 7, 2022, 11:06:15 PM3/7/22
to golang-nuts
Naming things is one of the hardest things a programmer needs to do. Seriously.
Reply all
Reply to author
Forward
0 new messages