Golang Is Good, Structure Is Bad
github.com
github.com
func NewBaz() Baz {
in a package called baz is already unidiomatic, in cases like that, the function should just be called `New`, leading to usage like: thing := baz.New()
which, to my eyes, is perfectly fine.Can't help but quote: "Design patterns are bug reports filed against the language" (Peter Norvig, iirc).
The author of the article should take some time to learn idiomatic Go. "[...] I can use packages as metaphore for classes" is a big red-flag that one doesn't have the fundamentals.
When one writes Go, writes in Go. Not in Ruby, not in Lisp, not in Haskell. In Go.
import requests
# uh-oh!
requests = []
for url in ['http://google.com', 'http://duckduckgo.com']:
with requests.get(url) as req:
requests.append(req)
You'll get AttributeError: 'list' object has no attribute 'get'
because your sensibly-named `requests` object is shadowing the module. Obviously you could re-name it to `reqs` or something, but having module objects in a top-level global namespace can sometimes non-trivially increase cognitive load.By comparison, R and Common Lisp have special syntax for accessing objects in namespaces. There are good and bad approaches to both. Having namespaces/packages exist alongside other objects makes it easier to reflect on their contents, obviating the need for specialized access functions.
Look at go's `net/url` package. The type is `URL` because it's exported, there's no `New` function. It instead uses the conversational `Parse`.
`url.URL` does stutter, and `url.Parse` probably belongs in the url module, with the type in `net` to reduce stutter.
This would make `net/URL` a clearer non-stuttering type. It would also make 'net/url' a library of functions with which `net/URL`s are manipulated and a clean-room fashion.
import (
. "fmt"
)
....
// now call function without prefix
Println("Read more docs")import ( . "fmt" . "log" )
func main() { Println("broken!") }