> Unlike other languages where you can just create a directory and get started, Go wants you to put things in $GOPATH.
I've seen this complaint a lot and don't agree with it. Go just want everything to be accessible through $GOPATH, it doesn't have to _be_ there. Here's how I organize my code:
- I have all my dev in ~/dev. Anything goes here, whether it's go, ruby,... it's my workspace
- I put $GOPATH where it should be, in ~/.local/share/go
- Whenever I need to go get something, it ends up in ~/.local/share/go/src/domain.com/author/package, as expected
- When I need my package to be in $GOPATH, I just symlink ~/dev/project to ~/.local/share/go/src/github.com/rakoo/project, so it is visible in $GOPATH
After that everything works as expected (modulo some minor quirks I have to do at go install time), and you don't have to have a specific workspace just for go. It's also minimal enough (once per new project) that I'm not too bothered by it.
Even easier: just put your files in a directory and run 'go build' in that directory. If you have libraries, put them down lib/lib_name/lib_name.go, and your build from the root directory will work fine. The compiled lib files will not be in your current directory, but that's usually OK.
For a working example, have a look at the logstash-forwarder code structure, it's how they do it, and you can build that from any directory you want.
And if you really want to set up go path in your current directory, use a make file and set up a target with 'env GOPATH=$(pwd) go install'
- libraries are duplicated left and right. If I want to use the same library in multiple projects, it will be in each project's lib (note that this is how you'd vendor, but it's something else)
- resetting env for each command you run sounds heavier, and the day will come when you will forget to do it and you'll run into problems.
Duplication depends on how you pull them in. For 3rd party libs, you'll pull them in via 'go get', and they will reside in the normal GOROOT, which is appropriate. It's just the libs you write for the particular project which would go down the local lib directory.
Resetting the env isn't my preferred choice, but if you put it in a make file, it becomes hard to forget. Especially if you are in the habit of reusing make files between projects with a few customizations, which is my preferred setup.
I don't think you are being realistic. It is a significant additional effort that other languages typically free you from. Not a big problem though, we can write our own tools.
It's only a symlink you create at the start of a new project (not even each package, each _project_), it's really not heavy. An additional step compared to other projects, but overall the cost of managing dependencies is still lower.
After about 6 months toying with Go, I also ended up doing the same, except on Windows. I need a personal directory where everything I create and edit is stored, and nothing more, so I can easily and frequently do a manual backup of the contents, without the zip containing anything I didn't create.
It's a pity though the $GOPATH system doesn't fit in with this style of working.
To me that criticism you quoted seems really misguided. A person who doesn't want to see performance measures from new users will never understand how they (the new users) are typically using the language and where the most common performance blocks are at the newbie stage.
It's important to understand how new users are using the language, but new users of the language should not be focusing on performance before they learn the language well enough to know what is idiomatic and what is not, which was the original criticism.
The criticism is well-grounded: it's rather tiring to see endless "performance benchmarks" that test little more than printing to the console[0], or create artificial programs that are direct line-for-line translations of another language, and don't represent what an actual developer would generally write.
Think of it as a from of premature optimization - literally.
[0] Not in Go, but I can't count the number of times I've seen people use these comparisons for languages like Python and Ruby. It's incredibly ironic, because these languages really just farm out to the same underlying C libraries for this functionality, so it's testing something, but not really the performance of the actual language features.
It's important to understand how new users are using the language, but new users of the language should not be focusing on performance before they learn the language well enough to know what is idiomatic and what is not, ...
See, that's a chicken-and-egg problem. This was my original point. How do you come to understand how new users are using your language and where they're taking performance hits if you keep telling them not to try to write performant code?
First you teach them how to write idiomatic code (non-performant), and then you teach them how to make the idiomatic code more performant.
It's very common for new users (in any language, not just Go) to try to jump right to the end, but focusing on performance before understanding basic language building blocks is a recipe for frustration, both for the new users and for the language designers.
>In a way, I consider that to be an advantage coming in to a new programming language, in that I have no preconceived notion of how things “SHOULD” be. I can learn the language and use the constructs as they were intended, and not have to question WHY it was designed that way because it’s different than what I know.
>I just could not get my non-functional mind to wrap around the functional Scala. And since I really didn’t need to code (nor the developers want me to), I gave up on learning Scala.
>I’ve barely heard of generics, communicating sequential processes, and other “cool” and “advanced” concepts.
No, because language features aren't a la carte, and when you pick a language can only weigh the combined pros and cons of each package deal. In fact, in many cases where the "Blub Paradox" card is played, that's actually what's happening: one language might be "linguistically" more powerful but another has better performance, or better monitoring, or a larger variety of available libraries, or even a specific library that you absolutely need. It is true that some languages can theoretically be categorically better than others (or, at least for certain domains), but in practice that usually applies to the compiler (i.e. the language itself) alone, and rarely to the entire ecosystem. Also, I find that people tend to vastly exaggerate the impact a specific language feature has over total productivity.
I've found that generics are really only 'necessary' for building libraries. If you are writing applications or utilities, then you probably don't need it very much.
Generics aren't necessary at all, but they are a powerful addition to the means of expression a language offers and have use cases beyond collections. So while it's not a deal breaker, it's definitely sad and hard to understand why they left them out. Especially when you know Java's history and the pain they went through when they finally added generics.
Yeah, true. I feel disappointed whenever anybody tries to tack generics onto an existing language. You can never really tell if it is done correctly or not.
Currently Go only statically links libraries. I thought I read in one of the roadmaps that they want to do dynamic linking down the line but I cannot seem to find that source anymore.
Yes and no. Pure go libraries are statically linked, but if you run 'psof' on a running go process on Linux, you will see open file handles to some shared libraries.
"I haven’t used this extensively, but in my attempt to optimize the integer compression library, I added different C and assembly snippets to try to squeeze the last ounce of performance out of Go. It was fairly easy and straightforward to do."
Ah, the famous integer compression library modifying non-programmer :)
haha. I think the title should read, "Go: From a Non-Programming,Masters in Computer Science,7 years penetration testing, quite proficient in Pascal-C-Perl-PHP-Java-JavaScript, high performance MQTT broker implementing total Noobie Perspective"
I've seen this complaint a lot and don't agree with it. Go just want everything to be accessible through $GOPATH, it doesn't have to _be_ there. Here's how I organize my code:
- I have all my dev in ~/dev. Anything goes here, whether it's go, ruby,... it's my workspace
- I put $GOPATH where it should be, in ~/.local/share/go
- Whenever I need to go get something, it ends up in ~/.local/share/go/src/domain.com/author/package, as expected
- When I need my package to be in $GOPATH, I just symlink ~/dev/project to ~/.local/share/go/src/github.com/rakoo/project, so it is visible in $GOPATH
After that everything works as expected (modulo some minor quirks I have to do at go install time), and you don't have to have a specific workspace just for go. It's also minimal enough (once per new project) that I'm not too bothered by it.