400 days of Go
philipotoole.com
philipotoole.com
I don't see why people have perception of IDE being a bad thing. In past 15 years or so, I have never been in a situation where I was on a system where some IDE was not supported, and I wanted to use it.
They are everywhere, just like vim. That's like mocking the Gmail cause it needs a browser, while praising mutt cause you can be lost in Jurassic World with an Apple II which cannot run Chrome.
The build times of Go 1.5 are not that fast. That point is not that valid. I also don't see much point in have competition of build times among languages that compile to binary. Rust, Go, C are all fast enough.
I'm sure he has good points below (I see testing as one), but he started out bashing Java, after which I genuinely did not want to read the article. I'm not a Java fan, but I find the language extremely non-assuming, very less opinionated and quite useful. If Go one day has half a million repos of libraries, given it's composability features, it will have names just as fugly as some Java classes. Java's standard libraries are actually very clean.
It's just a smell, it's not disqualifying, because, as you correctly state, rare are the times when you can't just run the IDE. But I think it's a perfectly fair point that the language you can write effective in vi is -- all other things being equal -- better than the language that requires an IDE.
The funny thing is that this feature also explains what Go is. Go relies heavily on the various tooling just to overcome the deficiencies of the language. It's just that they didn't choose IDE as a primary target, but instead various ad hoc tools.
For example, when I find the unused imports being a hard error inconvenient, a typical suggestion from Gophers is "just use an editor plugin that automatically handles that". This is exactly the same attitude that can be found in the IDE lovers.
And that's why I don't like Go anymore. In the name of the simplicity of the language, they concentrate on building more and more tools, rather than fixing the language. I'm pretty sure if Go acquires generics someday, it will have the form of code generation, which is proven to be awkward. (I heard "go generate" already does a part of that?)
Unused imports flagged as an error is great for production code, but infuriating during developing, when you need to work with a lot of tentative code, the most basic of which involves printing.
Having to add, remove, then re-add "fmt" or "log" just to keep the compiler happy is not a Unix-philosophical issue around language design, it's just an unnecessary strictness.
Go is "opinionated", but it tends to err on the side of impracticality, a kind of distorted, prematurely-optimized YAGNI that disrupts developer efficiency in the name of simplicity. "go get"'s obstinate simplicity is firmly in this category.
Go gets a lot of stuff right, of course. And the tools — the "go" tool, compiler toolchain, gofmt, debugger, godoc etc. — are clearly good Unix citizens, of course.
This sentence has baked into it a context which is not universal. Namely that "during developing" you are "work[ing] with a lot of tentative code". That's simply not how I, nor many others, develop. Even on the very first sketch of a program, I'm writing complete, valid types and functions. I code all of the error paths completely as I encounter them. For very large first drafts, I'll often stub methods or types, but I never leave the program in an invalid state and "try it out". (Tangentially, for what I suspect are similar reasons, I never quite understood why anyone would care so much about REPLs.)
All of the tentativity, so to speak, has been expressed and explored in my head and on paper beforehand. Go is a language that rewards, perhaps even demands, this style of development. If that's not how you operate, Go will feel like it's fighting you. But that's not a universal critique of the language, that's a very specific critique of your specific operating context.
Sometimes I write code like you do. At other times I'm "feeling out" a solution and want the language to not fight my half-baked, messy (but syntactically valid!) program. At other times I'm writing a quick and dirty script I will use today and never after; it doesn't need to be pretty, only functional. But Go wants your code to always be fully realized and clean, which just doesn't mesh with reality.
We don't need "universal critiques". Everyone has a style, and a good, mainstream programming language needs to be receptive to those styles.
It certainly meshes with my reality.
Otherwise, you get terrible products that are nothing more than the lesser sum of their features, like JIRA, or Scala.
I think this statement makes both points simultaneously.
If a piece of software can give my team a 1% speedup, it'd be worth $40k a year. Multiply that by lots of teams, we can see there is a big market on making engineers more productive.
Meh. People say the same thing right before starting a Node project with Sublime. Then they proceed to write an unmaintainable mess of JavaScript. With only the original author knowing who calls what, what gets returned, interface definitions, etc.
I have yet to find a language that doesn't benefit from a capable, intelligent IDE.
Also note that a carpenter building a house probably wouldn't choose the most powerful tools (tower crane, etc) even if financials were taken out of the equation.
It doesn't make much sense to compare go's standard toolchain to building a house without power tools. What an IDE gets you over a more unix-like toolchain is integration, nothing more. They have all the same capabilities, but an IDE is designed to make a specific prescribed workflow seamless. There simply is no good analogy for this, carpenters don't have a universal tool that acts as a nailgun, drill, power screwdriver, wrench and saw at the same time.
EDIT: Other stuff that's often gotten wrong are short variable/function names and spacing.
> But I think it's a perfectly fair point that the language you can write effective in vi is -- all other things being equal -- better than the language that requires an IDE.
I would have to disagree with this point as well. To me, it feels like suggesting that computing is better with punch cards. Because, it is then also a fair point that a way of computing that can be done without a computer and editor is -- all other things being equal -- better than the way of computing that requires a computer and editor.
I think that thinking this way will also help numb the next leap in methods of instructing computers, and performing computation. Whether that involves a programming language or not.
Maybe its just the code I've read, but its generally much longer than other languages to accomplish the same thing. A bunch of little things add up, such as "extends" instead of ":" for inheritance. Naming things is often longer - maybe its not the language core itself, but a counter example is python coding standards keeps them much shorter. With Go, there's duck typing to not have to declare obvious types (such as for strings).
The goals of the programs in enterprise java apps probably differ by an emphasis on readability and not writing speed. I.e. lambdas are written quicker to write, but maybe a reader would understand a strategy pattern's goal quicker.
Imagine you're refactoring a code written by employee #12340 that was written 10 years ago. With Go, you'd go file after file decomposing the program to finally figure out that if he just used a word to implement an interface, you only had to read that file and a javadoc. Long class names are still easier to look than signatures of functions.
Java emphasises abstraction. Go emphasises composition. Both have its uses, but what I was refuting was people claiming that Go is better than Java which I think is extremely uninformed conclusion.
This is not my experience with Java programs.
Enterprise Java programs often have many layers of magic abstraction, like Aspect-Oriented Programming, dependency injection, IOC.
Furthermore, people love using configuration files over code to determine program behaviour (see servlet configs, etc).
Not a Go developer, but I think you mean type inference, not duck typing.
You call it a smell I call it functionality. Get back to me when Go is at version 9 with decades of features added and then you can talk about verbosity.
And this idea that you need an IDE to code Java is pure and utter rubbish.
Because, actually, it doesn't matter a damn what tool or method you use to develop something - do you have a USER? No USER = failed project.
I'm personally of the opinion that those who depend on an IDE, in and of itself, are doing the computer world a disservice - because they are perpetuating the 'special' nature of computing by stint of becoming competent with an IDE. IDE's require an investment, they require a portion of your life - investing that portion of life in a product specifically designed to impose limits on your freedom of speech is a gamble, plain and simple. Some people win from such an action - others complain bitterly.
Either way, if your language and technology require a commitment of life, then it is either an enabling or an enslaving technology, to more or less a degree. Languages designed to free us from the requirement of using a specialized tool - which is what an IDE is - are of more or less value than languages that don't. And the key to this equation is: do you have a USER?
In short: use an IDE if it is necessary for you to gain a USER. Beyond that point however, do not promote technologies with such dependencies. The best computer technologies do not require a big investment on the part of the user. This is true of IDE's. Corollary: the more you have to invest in a technology, the less valuable it is - on the basis of how many users you eventually gain as a result.
Go seems to have taken a look at the carnage of decades of dependency hell and decided "if we make no effort to provide a system then people will be forced to produce sane stable APIs".
I've picked the short straw of trying to reproducibly build and package Go based projects for internal projects. The combination of go get and the Go ecosystem's cultural lack of versioning and stability are giving me a deep dislike of the language.
First you have to play git-bisect on the dependencies (after you've hunted them down because of repo renames) in order to find the most recent one it builds against (and who knows if that was the one written against!) Then you have to futz around to add in either some custom or third party vendoring script, and then you have to rinse and repeat for second order dependencies.
For example, take the author's own first linked project. Following the build instructions:
~ $ mkdir ~/syslog-gollector
~ $ cd ~/syslog-gollector
~/syslog-gollector $ export GOPATH=$PWD
~/syslog-gollector $ go get github.com/otoolep/syslog-gollector
package github.com/otoolep/syslog-gollector
imports code.google.com/p/log4go
imports github.com/otoolep/sarama
imports code.google.com/p/snappy-go/snappy: unable to detect version control system for code.google.com/ path
~/syslog-gollector $ go install github.com/otoolep/syslog-gollector
src/github.com/otoolep/sarama/snappy.go:5:2: cannot find package "code.google.com/p/snappy-go/snappy" in any of:
/usr/lib/golang/src/code.google.com/p/snappy-go/snappy (from $GOROOT)
/home/ldite/syslog-gollector/src/code.google.com/p/snappy-go/snappy (from $GOPATH)
Well, I'm shocked.There is furthermore, no way to build release packages that people can just install. There are no tarballs or jars or anything else that can be simply downloaded and depended on. So not only is everything tied to my github account I can't even release stable versions in any sane way. I never thought I would say "Man Java is really doing it right" but in comparison to Go it is!
I love writing in the language, but I solve this problem by mostly depending on only stuff I have written. That way I can at least control the problem. I have even started using submodules again! At least that way I can pin my dependencies to specific versions without having to use a third party tool. Insanity!
~ $ go get -u github.com/otoolep/syslog-gollector
warning: code.google.com is shutting down; import path code.google.com/p/log4go will stop working
warning: code.google.com is shutting down; import path code.google.com/p/snappy-go/snappy will stop working
~ $
Everything is fine (aside from the warnings about code.google shutting down).Yes, Go does not have a culture of versioning, but it _does_ have a culture of _vendoring_. You should be getting your reproducible builds by vendoring your dependencies. That way, you don't need to do any hunting or git-bisect shenanigans.
It is a fact, that the go dependency management story is weaker than nearly any of the other modern development environments there are. It is getting better through time, and probably won't a problem long term (and for many people isn't a problem now). But lets not act like it isn't a weakness.
As I said, I've been working with code I didn't write: I've effectively been taking other people's *hub code and vendoring it for them, because they haven't. This is not optimal.
And this isn't trivial projects, either, e.g. https://github.com/influxdb/influxdb/ (also connected to the author!) still uses trivial go get, and doesn't make any effort to help with vendoring.
The only way out is to get them focusing on a new cult instead, thereby changing their self-ego attachment to less broken and less dangerous ideas.
edit: lol downvotes
What language ecosystems do you feel have good dependency management?
It's based on the curated package server https://stackage.org which server sets of packages that are tested for compatibility.
I really like some of the decisions around Go, but I don't like Go itself, as a language. For web apps, at least. I've been looking at http://elixir-lang.org/ and http://www.phoenixframework.org/ and I really hope that they gain steam before Go does. I will continue to use Go for command-line apps, which I think it is very well suited for.
I guess a fair comparison would be like Linux how the many flavours others users variety and freedom, but it also complicates and often introduces subtle incompatibilities (albeit usually resolvable if you know what you're doing). And similarly the Go idiot is a double edged sword that sometimes enables it's users, and sometimes hinders.
The Go community can be really problematic and condescending. Which is another reason why Elixir appeals to me: you get treated like a person.
But if I'm in the middle of a project in language X, trying to do Y, then "shut up and do it the way we do Y in X" really might be the correct answer. Work with the tool, not against it...
That may sound trite, but it's not as bad as it sounds I think. As an example: People want to make their own map (or have a library that provides map) in go, but go just will not play ball. The algorithms and writing styles people had in mind that use map shouldn't be written, and if you legitimately cannot express a concept concisely without it, than that makes go a worse language.
The fact that Go doesn't have an official IDE is actually what stops me from going near the language.
That's not what the article claims, however. The author critizes languages that _require_ an IDE, not the availability of IDEs.
I have seen a guy on HN saying that debuggers are bad and logging debug messages is superior :). Future is here, but it is sooo unevenly distributed.
It's all about context. Go is a great tool for certain things. Understand the boundaries of those domains, rather than castigating the tool.
There is a general attitude in the Go community eschewing all sorts of complexity be it in the language itself or tooling and this attitude is toxic and stupid. It will prevent Go from becoming a serious language unless this nonsense about "simplicity" is left to perpetuate. There is nothing wrong with keeping a language elegant--cue a brouhaha about generics in 1... 2... 3...---but forcing this attitude to tooling is not a wise thing to do. A significant majority of professional devs do not write their code in vim without syntax highlighting, which is what some eminent members of the Go community seem to be in favour of. They need auto-completion, refactoring (which search and replace isn't), automated deployment and testing, debugging and project support.
I don't know what you mean by "forcing this attitude on the tooling". The only thing that people tend eschew a tool for is if it's too big, like ides tend to be. Go has a plan9 heritage, and therefore a unix heritage. People like the tools to be small and designed to integrate. The reason that I like writing go is because save for C, nothing else feels as unixy, as vague as that sounds.
It sounds like you ran into some hostility. If people are railing on others about their IDE usage, they're assholes, and assholes do tend to stick out. Go is opinionated, and while that tends to make for a cohesive ecosystem, it also attracts assholes unfortunately. Most go developers, though, while they aren't interested in an IDE for themselves, have no problem with someone else using one if they prefer that mode of working.
On the other hand, I'm with you on the fact that not having a good IDE is actually a bad thing. If you want to code with a single editor, that's fine, but IDEs boost productivity a lot once you learn how to use them. Not having a proper IDE is a minus for a language in my opinion.
Nothing controversial there.
So it's a little deceptive when some within the Go community argue that they don't need an IDE because half the time they're basically running their text editor as a lightweight IDE.
As an aside note there's also LiteIDE which, at one point, was the "unofficial official" Go IDE - if you will. A de facto recommendation for anyone new to Go and fancying an IDE. I'm not sure if anyone still uses it for any serious Go development but that supported a few more features that the average Go-enabled text editors didn't at that time.
http://thespanishsite.com and http://www.h4labs.com (on AppEngine)
I love the performance. They were in Python before. You'll notice the difference once you start to build things with lots of data like my little Swift "search engine":
If you are not going near a language for the lack of an "official IDE", you are really limiting your options.
Why would you need an official IDE, since many advanced text-editors can offer similar functionality ?
I can't stand reading this crap anymore. I'm using Spring for at least 3 years and never had to deal with such class names.
Though I agree that writing Java in vim is quite painful.
The bad news is that umpty million programmers tried Java before that happened, decided they hated it, and now will never look at it again.
As the saying goes, you never get a second chance to make a first impression.
I've written a go-style concurrency library for C for people who share this sentiment: http://libmill.org
These two sentences can't be both right. Most of the work in software development is maintenance. A tool that lets you ship bad code faster is going in the wrong direction.
If you'd have been using an IDE...
There are some being worked on, like delve (https://github.com/derekparker/delve/), which might be the most ambitious, but it's only recently becoming usable. The problem is partly due to my first statement, there's not a huge demand for these in the language ecosystem, so development has been slow.
I'm not sure if it would be nearly as helpful in Go to step through an chunk of unknown code that crashed, since python's execution is generally linear, whereas Go usually has a high degree of concurrency.
Build tool and language are somewhat separate concepts.
[1] https://getgb.io
The author only hesitantly added support for managing dependencies, which is done through a separate "plugin", gb-vendor. It maintains an internal manifest file which only the gb-vendor tool is supposed to manage. It's not like NPM or Ruby's Bundler where you the manifest file (package.json, Gemfile) is what you edit to produce the vendor tree. Support for branches and tags seems to missing, as does any notion of versioning, so of course semver is not on the table.
I understand the Unix philosophy of keeping dependency management and building separate tools, but I suspect that what most Go developers want is a fully integrated solution. I know I do.
Yet a decimal data type is missing.
If most languages had Decimals, I am sure only C/C++/Java diehards would use ints/floats instead. In fact most modern scripted languages should have them.
Regarding go, as it is a relatively new language, and having to interact with databases, with Decimal being a fundamental SQL type, yes, it should have Decimal.
In real world applications, it is one of the more essential non-collection types.
No, its more like "key" in the way that ints are.
Well, not quite -- less than ints, but more than floats.
Exact rationals are in a similar situation.
Also, nothing says "use the standard way" like making the built-ins the only thing that's generic...