Live data from Hacker News

Uber Go Style Guide

github.com

111–120 of 140 posts

Re: Uber Go Style Guide

#111
I'll throw in one request for functional options as written here: please don't use closures to capture the data.

If you use closures, it's nearly impossible to compare the results for equality in tests or code that might care to validate / deduplicate / whatever those args. You can achieve it with a moderate amount of heavily-implementation-dependent reflection (get the func type, construct arg(s), call func, check result), but that's about it.

Please just use values as the backing type. `type thing int` is utterly trivial to compare if needed, by comparison - just use `==`. Any code anywhere can construct the same argument in the same way and `==` to see if what they are checking is part of the args, and you're still not binding yourself to a specific implementation-type that'll later risk a compile-time failure.

(if users are casting to the private `int` type to check stuff, yea, it breaks - but the reflection-to-read-closure approach has that same problem, you can't stop it)

Also, in my experience, the "loop and apply" pattern tends to fall apart rather quickly, and you start wanting more complicated interactions between args / validation that you didn't pass both "include deleted" and "exclude deleted" and the second just silently clobbered the first. With values you can pretty easily loop and switch on the type and do whatever you need.

Re: Uber Go Style Guide

#112
post #98
post #93

Earlier quoted context omitted.

Most languages have a GC so there really is no ownership to pretend away (if you like, everything is owned by the GC). Rust can be super cool without inventing fake problems for other languages.

How is it a fake problem? Uber is copying slices it doesn't need to copy, suffering significant performance penalty, because it is too error prone in Go. Rust completely prevents this error.

It's a trade-off. Programmer's productivity versus theorically perfect ownership handling.

I think that rust fills the needs of applications with extreme requirements. A browser is in that niche. Not all software is.

Thus most of the time you don't have to inflict yourself the pain to work with it.

Re: Uber Go Style Guide

#113

This recommendation surprised me: if err := ioutil.WriteFile(name, data, 0644); err != nil { return err } I've often seen guides for many languages that say don't use an assignment as an "if" condition. It may be a typo, and so is a source of errors, or it hides errors. Many compilers warn about it, and some people will consider it poor enough to refactor it out. Of course it's not the assignment which is being teste…

It helps reduce uninitialised variables, and if the condition is false, you don't have an extra variable hanging around in the scope that could potentially be misused by the developer later.

Re: Uber Go Style Guide

#114

Not an expert, but could someone explain why it says: "Panic/recover is not an error handling strategy. A program must panic only when something irrecoverable happens such as a nil dereference." Why is that any more irrecoverable than anything else? (You can check if it's nil before referencing it, right?)

This would be preventing, not recovery.

Re: Uber Go Style Guide

#115
post #107
post #93

Earlier quoted context omitted.

Most languages have a GC so there really is no ownership to pretend away (if you like, everything is owned by the GC). Rust can be super cool without inventing fake problems for other languages.

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 "it won't crash" + "it's fast", but then there's a lot of other languages that have the first property and the second is not very appreciated, as seen in the rise of so-called Electron apps and web apps in general.

Re: Uber Go Style Guide

#116
post #100

Earlier quoted context omitted.

I think this is where Rob Pike got it backwards (in terms of one of his stated goal for Go). Go is a very effective tool in the hands of experienced programmers, without having to pay the cognitive load price of 'Mommy' languages. I am reminded of Bryan Cantrill's rant regarding threads in this context. Writing solid software is hard. It takes skill, experience, and serious battle scars. Tools and languages can help,…

Even the most experienced programmer can’t hold all of a million line codebase in his or her head. And that is the issue with a language like Go - you can be careful about the code you write but it doesn’t have static analysis enforceable constraints on code other people write that interacts with your code / data.

That is a seriously ridiculous proposition in my opinion. If you find yourself involved in a project that requires you to hold a "million" lines of code in your head, refer to above point I made regarding "team". Something has gone seriously wrong somewhere if that is the situation.

This should not be news to this audience on HN: proper software architecture, design, and development processes trump "language" any day, any time, any planet. Conversely, even the most 'profoundly correct' language in the hands of unprepared development teams can result in software disasters.

The human factor is still paramount in software development. That is my experience after decades in this profession and is not mere conjecture.

Re: Uber Go Style Guide

#117

Earlier quoted context omitted.

You can always write a borrow checker for Go and have the lifetime annotated in comments similar to how pre-3.7 Python type checkers worked. In Rust, the borrow checker is too a separate static analysis stage and not directly tied to code gen. There are Rust compilers without the borrow checker.

If you wrote such syntax on top of Go, it would no longer be go, it would be a new language you created. The go authors wouldn't accept it, the ecosystem wouldn't work with it, and it would be fighting an uphill battle rather than just using rust or building a new language. > There are Rust compilers without the borrow checker Then those compilers do not compile rust. They compile a bastardized version of rust whereb…

https://github.com/thepowersgang/mrustc is a Rust compiler without borrow checker.

Re: Uber Go Style Guide

#118

Earlier quoted context omitted.

I have found this to be true of everything other than byte slices, where the result is some of the worst bugs I've had the displeasure of tracking down. Many Go libraries like to offer passing a byte slice to reuse as a destination. Many Go libraries take byte slices or structs containing them as arguments. A common result is "loop over some input, read it into the reusable slice, pass the slice to the next step". It…

Ouch. I guess this would be a reason to use strings more, since they're immutable.

Someone using a string when they really want a byte array/slice would fail review on its face. Excepting external APIs forcing "strings" on us, we only use the Go string type for UTF-8 code unit sequences (and this is a common assumption in the Go world).

Re: Uber Go Style Guide

#119
post #107
post #93

Earlier quoted context omitted.

Most languages have a GC so there really is no ownership to pretend away (if you like, everything is owned by the GC). Rust can be super cool without inventing fake problems for other languages.

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…

Ok, then educate me—what is ownership if not the responsibility for managing (cleaning up) a resource? In my C and C++ days, I never heard of it refer to some kind of exclusive permission to mutate a resource (which seems to be your meaning), but rather as the responsibility to free the resource (as in “the owner must and only the owner _can_ free the owner resource”).

It seems likely that you and I are using different definitions, and yours Rust-specific (and therefore not meaningfully generalizable to other languages, especially those with GC).

Re: Uber Go Style Guide

#120
post #111

I'll throw in one request for functional options as written here : please don't use closures to capture the data. If you use closures, it's nearly impossible to compare the results for equality in tests or code that might care to validate / deduplicate / whatever those args. You can achieve it with a moderate amount of heavily-implementation-dependent reflection (get the func type, construct arg(s), call func, check…

are you saying you’re against the functional options approach?

can you provide an example of a testing difficulty you’ve had?

Post reply on HN