Live data from Hacker News

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

dave.cheney.net

201–210 of 237 posts

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

#201
post #138

So I don't know how to fly a commercial airliner, but I could probably figure my way around a small single prop airplane. That's basically the difference between Go and a language like Rust or C++ or any language that requires a lot of up front investment, but then let's you work at power level 9000. So yeah, Go will get you there. It will take you a lot longer to get there when you aren't going 600MPH, and you can c…

But Go will never be a data science language like python, because Go is too limited to express that domain. Python may leave you in the lurch when it comes to maintainability, but for some domains python is infinitely better than Go.

Go fanboys won't get it. They are too busy proving their language doesn't need Generics.

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

#202
post #131

I don't understand something. > 5.1. Consider fewer, larger packages > 5.2. Keep package main small as small as possible If you have one package, which is the main package, then how are you supposed to keep it small, and at the same time not creating more packages because somehow that is the work of the devil? He is telling me to try to fit everything into one package, but at the same time keep it really small. It is…

In golang packages named "main" are special. They're not importable and they correspond to a single executable. If you want to be able to reuse code in different packages in the future or have more than one compiled binary, you won't be able to put everything into a single "main" package

Right now I use many internal packages. It makes my code more organized. By many, I use 4-5 and the number probably is not going to change. I dunno if this is a good idea, but it seems like the best I have got that suits me.

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

#203
post #94

My advice would be this: If you have a specific reusable component.. Make a package to contain it. Use init() to compile any regular expressions and store them as variables within that package, so that you don't Split out related code in a folder, remembering that the included code is done in alphabetical order - so shared functions within the same package you should alphabetically make it the first to be included. Y…

> One last thing with error handling. Everybody does if err!=nil. I tend to go the opposite way, if err==nil and nest these, if err isn't nil i drop out and deal with the error. If it is ok, it will return ok.

Don't you get "staircase of doom"?

    err := unsafe1()
    if err == nil {
        err = unsafe2()
        if err == nil {
            err = unsafe3()
            if err == nil {
                err = unsafe4()
                    if err == nil {
                    err = unsafe5()
                    if err == nil {
                        // ...
                    }
                }
            }
        }
    }

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

#204

Earlier quoted context omitted.

https://github.com/vlang-io/V/blob/master/examples/users.v They are very simple and combine Rust's Option and Result .

What's the difference between "break" and "continue" inside an or-block? Or do they apply to the outer enclosing loop if there is one?

Yes, just like in Swift.

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

#205

Great article, as always, by Dave Cheney. I took a lot of his advice when designing V [1]. It's very similar to Go, but it has - No global state - Only one declaration style (a := 0) - No null - No undefined values - No err != nil checks (replaced by option types) - Immutability by default - Much stricter vfmt - No runtime - Cheaper interfaces without dynamic dispatch [1] http://vlang.io

This is interesting. Go proclaims itself as a modern spiritual successor to C, but I think what you've done is much closer to that goal. BTW, if you're going for immutability by default, perhaps swap := and =? Reason being, if variables are immutable by default, assignments should be far less common, so the language should discourage them with more verbose syntax over initialization of immutables. Besides, C original…

I agree with you, but I want the language to be not too different from C/C++ and Go, to make the transition easier.

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

#206
post #148

Earlier quoted context omitted.

Totally agree. If you have to scroll up to be reminded what some variable means, a longer name is good. But if its usage is a few lines away from its declaration then there's no reason to add visual noise to your code.

Its easier said than done though. We started following this few years back but then while it was "few lines away" originally, code evolved and now there are parts where its 20+ lines away. This means that short var names need to be continuously "enlarged". Well, then why not start with a "medium" name and avoid all that headache? ctx is a good enough compromise between c and context. (c can be client, config, context…

Rarely do you have a case where a variable outgrows its simple name (and value) and you keep it the same. Even when a function adopts new characteristics it's advisable to change it's name or make a new one. If you initially had variable `i`, created and destroyed in 5 lines of code but that has grown to 20+ lines, I'd recommend you (1) not add the 15+ if it could be put in a function (you get to name that section of the code), or (2) rename the variable. But a 5-line code that becomes 20+ lines is both strange and interesting.

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

#207
post #62

Earlier quoted context omitted.

I feel like I have the opposite problem. If the name is more than a few characters long, it starts to become non-instantaneous to recognize it. Things get much easier to follow with visually-instantly-recognizable symbols. So in conditions where a variable is used over a short area in the code (or where it's used _constantly_ over a wide area), I prefer short variables.

Dense code that benefits from dense variables(which describes a lot of "pure algorithms" work) I often approach by aliasing the variables to shorter ones. It's all in the same body so the context is not especially hard to lose.

IMHO short is OK as long as the name makes sense and is easy to connect to the real meaning. For instance "msg" is perfectly valid name for a message var, and even "m" in some short snippet of code is obvious, but calling it "a" or "x" or something completely unrelated like that is a bad idea. In matter of fact calling it something too neutral like "data" can also be as bad if it's not clear which data you mean. Context is everything in making it easy to understand.

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

#208

Earlier quoted context omitted.

An example where I disagree, and use 1-letter names daily: arrow functions in both Java and JS. `usersList.stream().forEach(u -> someSet.add(u))` It's immediately obvious that u is a user in usersList. I realize that it's debatable if u is really more readable than spelling out user, but I prefer it, and I don't think anyone is going to be confused by it. If the chain does get really long, also, I will spell it out e…

Shouldn't you be able to write that as `usersList.stream().forEach(someSet.add)` For Javascript at least that would work.

I haven't written Java since like java 5, but I believe java 8 has syntax for this as well:

`usersList.stream().forEach(someSet::add)`

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

#209

Earlier quoted context omitted.

> For a local variable, the name i conveys as much information as index or idx and is quicker to read This is only true because i is a specific, common abbreviation for index. When writing arbitrary glue code, a single letter variable would be a meaningless abbreviation without shared context. If you encounter "i" and it doesn't mean "index of a for loop", you're going to be taking additional time parsing meaning.

An example where I disagree, and use 1-letter names daily: arrow functions in both Java and JS. `usersList.stream().forEach(u -> someSet.add(u))` It's immediately obvious that u is a user in usersList. I realize that it's debatable if u is really more readable than spelling out user, but I prefer it, and I don't think anyone is going to be confused by it. If the chain does get really long, also, I will spell it out e…

Sure, for a lambda I think it’s arbitrary. For larger functions / classes it matters

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

#210
post #148

Earlier quoted context omitted.

Totally agree. If you have to scroll up to be reminded what some variable means, a longer name is good. But if its usage is a few lines away from its declaration then there's no reason to add visual noise to your code.

Its easier said than done though. We started following this few years back but then while it was "few lines away" originally, code evolved and now there are parts where its 20+ lines away. This means that short var names need to be continuously "enlarged". Well, then why not start with a "medium" name and avoid all that headache? ctx is a good enough compromise between c and context. (c can be client, config, context…

This wouldn’t likely be hard to write a linter for: is the name 1-2 letters other than a method receiver, “i” or maybe “j” and is referenced more than 5 lines from where it’s declared? Lint warning.
Post reply on HN