Programming language compilers and interpreters have no opinion on how a piece of code is formatted. As long as it has all the right braces and parenthesis, etc. they will produce executable instructions. Because of this it's quite possible (and common) for code to rot into a nasty, inscrutable mess.
Of course you should have well-established style guides and your editor should probably point out bits of code that doesn't conform to the guide, but sometimes we humans are just lazy. Several years ago I started using Go and fell in love with go fmt
(and goimports
). Well, not really the exact style of go fmt
s formatting, because sometimes it does strange things. As the Go Proverbs state:
Gofmt's style is no one's favorite, yet gofmt is everyone's favorite.
The reason everyone loves tools like go fmt
is because you can plug them into your editor's onSave()
hook and from that point on you never have to worry about manually formatting code again. Oh, except that sometimes you still do (at lease, I do)...
Here's an example of what I mean using the excellent and quite minimal 'httprouter' library from Julien Schmidt:
router := httprouter.New()
router.Handler("GET", "/foo", fooHandler)
router.Handler("POST", "/foo/bar", fooBarHandler)
router.Handler("DELETE" "/baz/foo/bar", bazFooBarHandler)
router.Handler("HEAD", "/bar/baz", barBazHandler)
This code is fine, sure. But there's only 4 registrations and they aren't very complicated. I'm not opposed to a bit of manual code formatting beyond what tools like go fmt
provide. So, I would love to be able to format the about routes more like this:
router := httprouter.New()
router.Handler("GET", "/foo", fooHandler)
router.Handler("POST", "/foo/bar", fooBarHandler)
router.Handler("DELETE" "/baz/foo/bar", bazFooBarHandler)
router.Handler("HEAD", "/bar/baz", barBazHandler)
Hmm, things are lined up, but it just looks strange, doesn't it? And go fmt
won't allow multiple spaces between function arguments, so that's not going to work. How about a convenience function that accounts for manually inserted whitespace in the string values?
func Route(router *httprouter.Router, route string, handler http.Handler) {
// Split the string on all whitespace values, even congiguous ones:
fields := strings.Fields(route)
method := fields[0]
path := fields[1]
router.Handler(method, path, handler)
}
Which allows us to turn this:
router := httprouter.New()
router.Handler("GET", "/foo", fooHandler)
router.Handler("POST", "/foo/bar", fooBarHandler)
router.Handler("DELETE", "/baz/foo/bar", bazFooBarHandler)
router.Handler("HEAD", "/bar/baz", barBazHandler)
...into this:
router := httprouter.New()
Route(router, " GET /foo ", fooHandler)
Route(router, " POST /foo/bar ", fooBarHandler)
Route(router, " DELETE /baz/foo/bar ", bazFooBarHandler)
Route(router, " HEAD /baz/foo ", barBazHandler)
Voila! Now it's super easy to visually line up the similar elements. Ok, now you are realizing the kind of nit-picky person I can be. Can we still be friends? (FWIW, I like you just the way you are!)