4 ms·
Go is absurd. It's opinionated in all the wrong ways. > Functions that return something are given noun-like names. > // Good: > func (c Config) JobName(key st
by throwaway2203 4y ago
Go is absurd. It's opinionated in all the wrong ways.
> Functions that return something are given noun-like names.
> // Good:
> func (c Config) JobName(key string) (value string, ok bool)
> A corollary of this is that function and method names should avoid the prefix Get.
> // Bad:
> func (c Config) GetJobName(key string) (value string, ok bool)
That's dumb. I'd like a function to be GetJobName to indicate that it doesn't mutate anything. Maybe CreateJobName to indicate mutation. Just JobName is useless.
The other day, I spent a whole day trying to figure out the "idiomatic" way to return a an object not found case from my db. Do you return a nil pointer (don't, passing pointers leads to bugs), or an empty struct (then how do you reliably "test" its emptiness?) or an error? And of course, there's no real hierarchy of errors, no built-in extensible handling of errors that is semantic and makes sense, so every project just goes and reinvents their wheel.
- Thaxll 4y agoIf you rely on naming function to know if things can be mutated you're doing things wrong. The only source of truth is the type received.
- throwaway2203 4y agoWhy? Let's say I have a table full of cars and have a method > func Car(id string) Car How do I know whether it fetched that from the database or created a new one and returned that to me?
- Thaxll 4y agoOnly the type Car matters, why would the function name tells you anything about mutation? It does not tells you if you receive *Car or Car or if it's a Car but pointers inside.
- notpushkin 4y agoBecause I want to know what function does?
- Thaxll 4y agoI think it's not possible to achieve with func name on its own, the closest thing I see would be comments on the function but again not reliable imo.
- throwaway2203 4y agoAbsolutely not reliable. Comments get stale faster than anything else in the codebase.
- wizhi 4y agoAssuming Car() is a receiver function, you should be able to infer "how" the Car is "fetched" based on the type receiving the function call. func (d CarDB) func Car() (Car, error) The above tells you everything you need to know. As for usage, again, the type and now also the variable names should let you infer everything you need. func f(db *CarDB) { c, _ := db.Car() } The function name makes as little of a guarantee as to the underlying "how" as these other factors.
- Zamicol 4y agoI mostly avoid getters/setters in Go code, unless I have a lot of functions all related to the same thing similarly named. It's the return type that denotes the return. It's already in the function signature. That advice is a consequence of Go expecting function signatures to be read and understood. That's not the right choice for all programming languages, but for Go it works.
- throwaway2203 4y agoI mean, you can't get around database CRUDs. I'm not talking about setting a private variable and getting or setting it (that doesn't seem like idiomatic Go at all), but using the logic described above, you can't know whether a method with a noun-based name is a Read or a Create.
- euroderf 4y agoShouldn't a Create have the form NewBlah ? Incidentally warning that there is a memory allocation.
- robertlagrant 4y ago> I mostly avoid getters/setters in Go code, unless I have a lot of functions all related to the same thing similarly named. It's the return type that denotes the return. It's already in the function signature. But I thought Golang doesn't have function overloading, so you also have to name the function appropriately for its use?
- throwaway2203 4y agoYupppp. But you can't let function names get too long or everyone will laugh at you for being a Java dev writing Go. Like I said, absurd.
- Beltalowda 4y agoJust assume that "Noun()" gets the noun and it's effectively the same as "GetNoun()". Of course, nothing in the language prevents you from using "GetNoun()" if you strongly prefer that. > The other day, I spent a whole day trying to figure out the "idiomatic" way to return a an object not found case from my db. Do you return a nil pointer (don't, passing pointers leads to bugs), or an empty struct (then how do you reliably "test" its emptiness?) or an error? sql.ErrNoRows is often used for this.
- michaelcampbell 4y agoOne more cognitive jump to get to the point. Programming languages are for people, so reducing any mapping between what is written and what is meant is for the better. Adding more jumps, however easy, is rarely the right thing.
- Beltalowda 4y agoIt's just what you're used to. Anyone can make up some pseudo-scientific "cognitive" gobbledygook ("fewer words mean less language processing cognitive overhead"), but it really is just a matter of "what you're used to".
- jrockway 4y ago> That's dumb. I'd like a function to be GetJobName to indicate that it doesn't mutate anything. Maybe CreateJobName to indicate mutation. Just JobName is useless. It can't mutate anything with a non-pointer receiver. Mostly. > how do you reliably "test" its emptiness See time.IsZero() for an example.