Live data from Hacker News

Uber Go Style Guide

github.com

131–140 of 140 posts

Re: Uber Go Style Guide

#131
post #70
post #55

Earlier quoted context omitted.

No, the point of this observation is that Go exposes this complexity, it just doesn't make it explicit.

Language fight! Definitely I think that's a good discussion to promote on a thread about _a style guide for a language_!

Language fights are of the things many of us enjoy most about HN. Would you go to a metal show and complain about the moshpit? Just stand safely to one side and enjoy the vibe, man.

Re: Uber Go Style Guide

#132

The preference of channel size being unbuffered or just 1 is interesting. That seems like something specific to a problem domain; for instance, in projects I am working on now, having a large buffered channel (1000s deep) is useful for worker queues of thousands of goroutines, that all read from a task feeder channel. This type of queuing seems go-idiomatic, and negates the need for additional synchronization. In thi…

Why having a 1000s buffered channel is useful in this case? If it's unbuffered, you still get the backpressure blocking on writers as a feature, since you have a worker queues of thousands of goroutines to read and handle them.

That's a good point, at steady-state, I'd imagine unbuffered channels would have the same throughput as a deeply buffered channels. The main advantage is being able to spool up faster and smooth out throughput, but it could be for most workloads that is not valuable enough. Perhaps I placed too much value on that.

Your comment (and others) have convinced me to do some more empirical testing and see how necessary buffered channels are for my goal.

Re: Uber Go Style Guide

#133
post #121
post #90

Earlier quoted context omitted.

+1. It is quite an achievement by Go as a language and/or community to have generally short lines of code where two columns fit in a regular website width. I don't like everything about Go, but it's usually pretty easy on the eyes for this reason.

I don't think that the prevalence of single letter variable names can be considered an achievement (which is how they get short lines to begin with). It's quite a hindrance to readability. golang as a language does nothing to support shorter lines.

> golang as a language does nothing to support shorter lines.

It does a few things.

- Most declarations, including method declarations, take place at the top level. This is unlike most languages which declare methods one level indented along with the object's fields.

- Short type definitions (`type T1 T2`) are encouraged and often used for any repeated non-scalar type. This shortens argument specifications and (if a good name was chosen) improves readability.

- Anonymous struct fields are shorter both to declare and use. In class-based OO this is often the case for subclasses but not wrappers/facades. Go's approach covers both.

- Go linters push people to avoid `if x { ... return a } else { ... return b }` in favor of `if x { ... return a } ... return b`. I actually hate this, but it does keep indentation down.

- The lack of exception handling means there is a constant "pressure" to push errors back up manually, via early return if it's locally unhandled or to the top of the current lexical scope of it is. The result is definitely verbose and one of the easiest parts of Go to criticize - but the same pressure results in short (but plentiful) error handling lines.

(I do agree the majority of savings comes from short variable names, though I disagree that it affects readability much for the case of _variable names_ - struct fields are another issue...)

Re: Uber Go Style Guide

#134
post #115
post #107

Earlier quoted context omitted.

I'm sorry, but that is a naive misconception. "everything is owned by the GC" is a sign of not understanding concept of ownership, BTW. GC is not an actor in the system, so does not participate in the ownership. A Java finalizers might kind of do stuff, but that's when all references are gone, so they have exclusive ownership. Anyway... Languages with GC still do have ownership. It is just defaulting to be the most p…

"The only reason people don't notice that is because they do it incorrectly and it works most of the time, so they are unaware." Ironically, that's Rust biggest problem: not using perfect ownership management works for most software most of the time and that's good enough for most people and companies. You probably can't sell ownership management as a feature. The only thing that Rust can sell and that makes sense is…

Sure. SWE is not a first industry where you can get away with cutting corners or straight incompetence. And some people are going to write a code taking care of ownership by experience, skill, etc. and they don't need Rust. They might not know they are taking care of ownership, and yet do it correctly. Rust is only formalizing and verifying it.

I think in time more and more people and teams will discover that doing stuff with Rust is just cheaper and more productive. You learn ownership once, you get great results ever after.

Re: Uber Go Style Guide

#135
> Use go.uber.org/atomic Atomic operations with the sync/atomic package operate on the raw types (int32, int64, etc.) so it is easy to forget to use the atomic operation to read or modify the variables. go.uber.org/atomic adds type safety to these operations by hiding the underlying type.

I don't agree with this guideline. When you anyway have to remember to invoke an intrinsic function on the variable (unlike, say, operator overloading), I wonder why it's necessary to include yet another dependency that's just a wrapper for sync/atomic all because the developer doesn't pay attention to the right use of atomics.

Re: Uber Go Style Guide

#136

Earlier quoted context omitted.

In Rust, we also say that it’s the right to destroy.

Thanks for responding, Steve. I understand that “ownership” implies the right to destroy in any language. The bit I’m not so clear about is whether or not there are other rights/responsibilities (such as the right to mutate) as the OP suggests and whether a definition that includes those rights/responsibilities can meaningfully apply to any language or just Rust.

I think they’re talking about the borrow checker, which is technically distinct from ownership.

Re: Uber Go Style Guide

#137
post #105
post #99

Earlier quoted context omitted.

Ownership is different than mutability. Yes, immutability would prevent those errors.

The point is that ownership also prevents these errors. If there are never two simultaneous mutable references to something, then you can get the advantages of immutable data structures without paying the performance penalty.

We’re having a semantic debate. Ownership appears to mean something different to Rust folks, which is fine. I agree that Rust’s borrow checker (what you appear to be referring to as ownership or the enforcer thereof) prevents errors and is generally very cool. It’s just not what I understand ownership to mean.

Re: Uber Go Style Guide

#138
post #121

Earlier quoted context omitted.

I don't think that the prevalence of single letter variable names can be considered an achievement (which is how they get short lines to begin with). It's quite a hindrance to readability. golang as a language does nothing to support shorter lines.

> golang as a language does nothing to support shorter lines. It does a few things. - Most declarations, including method declarations, take place at the top level. This is unlike most languages which declare methods one level indented along with the object's fields. - Short type definitions (`type T1 T2`) are encouraged and often used for any repeated non-scalar type. This shortens argument specifications and (if a…

> - Most declarations, including method declarations, take place at the top level. This is unlike most languages which declare methods one level indented along with the object's fields.

You can do the same in C++ or Kotlin, etc., but you don't find people saying that those automatically make lines shorter.

> - Short type definitions (`type T1 T2`) are encouraged and often used for any repeated non-scalar type. This shortens argument specifications and (if a good name was chosen) improves readability.

Also possible in C++ or Kotlin, among others.

> - Anonymous struct fields are shorter both to declare and use. In class-based OO this is often the case for subclasses but not wrappers/facades. Go's approach covers both.

This can save lines of code (at the expense of not being able to easily figure out what classes implement or embed other classes or interfaces), but does nothing to shorten lines of code.

Same applies to error handling. Returning early can be useful in certain situations, but cause readability issues in others. golang linters did a bad job here as you point out.

Re: Uber Go Style Guide

#140
post #138

Earlier quoted context omitted.

> golang as a language does nothing to support shorter lines. It does a few things. - Most declarations, including method declarations, take place at the top level. This is unlike most languages which declare methods one level indented along with the object's fields. - Short type definitions (`type T1 T2`) are encouraged and often used for any repeated non-scalar type. This shortens argument specifications and (if a…

> - Most declarations, including method declarations, take place at the top level. This is unlike most languages which declare methods one level indented along with the object's fields. You can do the same in C++ or Kotlin, etc., but you don't find people saying that those automatically make lines shorter. > - Short type definitions (`type T1 T2`) are encouraged and often used for any repeated non-scalar type. This s…

> You can do the same in C++ or Kotlin, etc., but you don't find people saying that those automatically make lines shorter.

I don't know what happens in the Kotlin community, but you absolutely find people saying C++ is "less nested" than Java/Python/JavaScript/etc (and claiming it as an advantage and disadvantage depending on their viewpoint).

I don't know what you're really arguing with here. Go gives you a construct that makes lines shorter than most other OO languages. It's not "automatic" as it's a feature of the language someone had to design - but regardless it is shorter.

> [Short type definitions are] possible in C++ or Kotlin, among others.

Again I don't know Kotlin, but no, it's not possible in C++ (at least up through the 11-and-a-bit I work with). The equivalent C++ would be "struct T1 : public T2", plus another line of "{}". And it's rare (for good-ish reasons) to subclass specializations of the default containers rather than wrap them.

> [An anonymous structure] does nothing to shorten lines of code.

I don't see how this is a debatable point. Not having to specify the field name in the definition is a shorter line than than having to specify it, strictly so. Not having to specify the full path to such an embedded object to call a method or access a field is nearly always shorter (it can be longer if your struct name is longer than your field name would have been and you have an ambiguous resolution - the former happens a lot, the second less, and both in combination even less).

> Returning early can be useful in certain situations, but cause readability issues in others.

Regardless, it keeps the lines short.

You seem to want to argue "Go is ugly", which, fine. But the claim was "Go doesn't do anything to help make shorter lines." It does quite a bit.

Post reply on HN