Hacker News new | ask | show | jobs
by BreakfastB0b 1244 days ago
> Go keeps my coworkers from writing code that's too clever for me to understand

Until someone whips out `import “reflect”`.

I’ve always found it confusing that people claim Go is simple when it contains runtime type reflection, which is hiding just under the surface of lots of the standard library like `json.Marshall`. Trying to explain to a new Go developer why []int isn’t assignable to []interface{} is always fun.

2 comments

if you let people use reflect in non testing, that's on your reviewers and training.
So Go only keeps your coworkers from writing code that's too clever for you to understand if you don't let them write certain kinds of code? But then Go isn't doing anything, and it's you who's keeping your coworkers from writing code that's too clever for you to understand.
People can write bad code in any language if you let them. Film at 11.
Right, that's my point. I'm trying to refute the claim that Go is somehow an exception to that rule.
Go can be better at this without being perfect at it. No one worth talking to would claim go prevents all bad or confusing code.
reflect is *ubiquitous* in go code, though. It's just barely hidden under many of the most commonly used standard library functions: like those in the encoding and error packages, for example. It's like Rust's "unsafe": the admonition is "don't use it", yet even a cursory audit of popular Rust crates shows that "unsafe" is everywhere.
How do you square that away with its use in the standard library, and many third party libraries? Someone’s gotta write the reflection code.
I’ve not worked with Go (although I did read The Go Programming Language), but use in a library is a different beast than use in an application. In Java-land (where I make my money these days), I would reject any pull request for application code that used reflection but at the same time, I happily use libraries that push reflection to its limits.

To take one common use case for reflection, Json marshalling/unmarshalling, if I were writing an application that needed to do this, and for some reason I could not use a library, I absolutely would not use reflection, but would write code that specifically targeted the classes that I was marshalling/unmarshalling. Conversely, if I’m writing a library, I don’t know what those classes are so I must use reflection to manage this. That’s the key difference here.

You aren't writing std lib.
If you're using `json.Marshal`, you're using `reflect` [0]. It's slow and it's an absolute gold mine for runtime errors, but sometimes it's the best tool for the job.

[0] https://cs.opensource.google/go/go/+/refs/tags/go1.19.5:src/...

Are there alternatives ? I thought everybody was using the go stdlib for json marshalling..
Why isn't []int assignable to []interface{}? It's 6am and my brain hasn't kicked on yet.
They have different runtime representations. []interface{} is a slice of fat pointers to interfaces.