Take the following Go program.
package main
import "fmt"
import "json"
type Foo struct {
Wham int
Bam string
}
type Bar struct {
gee int
whiz string
}
func main() {
var f Foo
f.Wham = 42
f.Bam = "hello world"
msg, _ := json.Marshal(f)
fmt.Println(string(msg))
var b Bar
b.gee = 42
b.whiz = "hello world"
msg, _ = json.Marshal(b)
fmt.Println(string(msg))
}
Before knowing any better, I would have guessed the program produces two lines of JSON, with each line populated by two fields. But what the program actually produces is as follows.
{"Wham":42,"Bam":"hello world"}
{}
In other words, the first object is converted to JSON, but the second one isn't. The reason why has to do with what, in my opinion, is a design flaw in Go.
Go, like some other modern languages, tries to prevent style-and-format jihad from breaking out between developers by forcing them to use a specific style. Relevant to this case is that Go determines whether a member is public or private depending on the capitalization of the member's name. Lower case members are private; uppercase members are public. No argument.
Until now, during my tentative forays into Go, I've perceived this as a harmless quirk of the language. But when using the standard json
package, it's not harmless.
The json.Marshal()
function, which converts arbitrary Go objects into JSON-formatted strings, works only on public members. All lowercase members are ignored. In other words, you can't use Go and JSON and lowercase names—at least, not easily.
Normally, I don't care about style requirements imposed by languages. I adopt a when in Rome attitude and squash opinions about how code ought to be formatted, instead formatting my code the same as the language's standard library. But by using JSON it's nearly certain I'm interfacing between two or more languages—e.g., Go and Javascript—and in this case Go's quirks are imparted onto those other languages.
In Javascript I use camel-back notation for member names, thus matching the convention of the language. But I can't use camel-back for members of a JSON-derived object if that object is ever accessed in Go. Fortunately, Javascript is flexible and doesn't care how I name members, so I can make things work by using uppercase. But still this highlights one way in which imposing style on developers is problematic.
By the way, I'm aware that today is Saturday, just as I was aware that I last posted on Wednesday and that this week's blogging schedule differs from my regular Monday-Thursday. I assure you the oddity has nothing at all to do with how I've lost track of what day of the week it is because of my unemployment. Rather, I wish to post three times this week. That is all. It shan't happen again!
5 comments:
MVC code-first does some stuff like this as well. It's ironic that those design decisions are (I think) intended to make the language/framework easier to learn. Instead, they leave experienced developers scratching their heads trying to figure out schizophrenic behavior.
You lost me at hello. -- BW
Chad— Go's styling issue detracts from what is otherwise a language that innovates in all the right ways. Keep in mind Go isn't a marketed language. It's not a platform, it's not locking anyone in to anything, and it's not making anyone any money—not Google, not directly anyway.
In the case of Go, I think the styling issue isn't meant as anything; it's just a preference of the language designers. As it happens, it's a strong enough preference for them to wish to mandate it on everyone who uses their language.
Anonymous Bobby— Sometimes Just Enough Craig is too much.
This bothered me too, but apparently it's possible to get around it...
Anonymous— Thanks for pointing that out. Though I've known about json tag values for a while, your comment makes my post a little less wrong.
Post a Comment