Why does this article only compare Go with interpreted languages at the top? Go is a compiled language; wouldn't it be more fair to compare it with other languages that can be compiled, like C++, Rust, Haskell, or Lisp/Scheme?
I mention this because the article acts as if getting rid of abstraction layers between the OS and the code is a new idea. No, that's how all compiled languages are... that's the point of compiled languages. I suppose Go's most common use case lines it up against a bunch of slow interpreted languages, but really there's no reason except good libraries that you can't use the other compiled languages I mentioned for web apps.
Author here. I was comparing things that I have developed software in. It would seem unfair to compare things that I have not actively contributed production code and deploy. I mainly write web applications (services) of which C++, Rust, Haskell or Lisp/Scheme are not languages I find compelling to write web applications with. Would love to hear if you find this otherwise.
No, I honestly know next to nothing about web apps programming. I do know there exists decent-looking support for web apps for Rust, Haskell, and Scheme (Racket, but Racket isn't compiled to a binary), but I don't have the knowledge base to assess how good web programming is in these languages, if it's even good at all. I know this website is written in Arc (a Lisp). https://github.com/wting/hackernews
There are some nice things about writing web apps in Lisps, since one can represent HTML as s-expressions, e.g. (:html (:body ((:p (:class "main")) "Foo bar baz."))). And of course macros mean that one can create nice abstractions quite difficult or impossible in other languages.
Go advocacy tends to ignore what other modular languages with native compilers offer since the early 80's, as well as, present a cut down version of what modern runtimes are capable of.
If you read any posts or listen to any talks by Google's Go team, they are a fairly modest about Go. They know it isn't as fast as it could be (since they don't have decades of compiler optimizations yet that GCC or other compilers would give). As well, it's just a newer language. One thing a lot of people don't always realize is Golang started with the Plan9 C compiler[0]. So they actually generate all the way from source to machine code with their own compiler toolchain (no LLVM, GCC, or other compiler required).
When you look at the people coming to Go, most are coming from Python or Ruby, not C, C++, or Java. So a lot of the experience Go developers have are those other languages. As Rob Pike pointed out 2 years ago[1], while they set out for Go to replace C++, it ended up actually being a much better fit for Python and Ruby developers.
It's actually a really great fit for C# and Java developers too... C# guys like it because it's cross platform and they get to stop the madness of worrying about what version of the .Net platform is installed. It's also nice to have a single executable and not 100 dlls to deploy... no more need for an installer to do everything for you, just drop an executable.
I would imagine it's similar for the java guys, especially now that there's java 8, you start having to worry whether it's installed etc. I think Java is a harder sell, because most Java guys don't recognize the complexity inherent in their huge type systems, and they have all these new toys to play with in Java 8 without having to learn a whole new language.... I think they'll come around eventually, though.
Go happens to also be a really great alternative to C and C++ (at least in applications where you don't need the strict timing of a GC-less language...) It's much less error prone than C and C++, with memory safety making most truly critical security bugs simply impossible. Again, like the Java guys, it's a little hard to convince people that have been working in the language for 15-20+ years that there's something that can make their lives easier...
I didn't really know what eco-system you were talking about, so I looked at your comment history, from that I assume you're talking about Java.
So, I really didn't mean to denigrate any communities or languages, there's definitely nothing intrinsically wrong with Java, and the ecosystem is at least an order of magnitude larger than the one for Go. Java guys have probably the least reason to switch to Go of all the languages I mentioned. I can certainly understand why a Java dev would look at Go and wonder why anyone would ever choose it over Java.
Go isn't likely to beat many languages on features, since it was purposely designed to have fewer features than most other languages. I do think it offers some advantages over Java, but Java also offers some advantages over Go. It's not a contest. No one has to "win". There's a time and a place for nearly every language.
You got it almost right, I also do know C++ and .NET quite well. My fault for not expressing myself correctly.
However I find both your answers quite faire.
My pet peeve is more with younger developers that promote Go vs other languages, without knowing how rich they actually are. Or the alternatives that came before, lost in the mist of time, with similar features.
Nowadays I do find that Go is a good and safer alternative, for C programmers doing applications that can live with a GC.
For other backgrounds in languages with native compilers available, I guess we have to agree to disagree. :)
Java, while compiled, isn't compiled to machine code, and the bytecode to which it is compiled is run on a virtual machine. For this reason, I consider Java more of an interpreted language than a compiled language per se.
Ah, true. I guess I didn't mean to call Java slow, but interpreted languages in general (at least, their reference implementations) are pretty slow. You're right... Java's kind of in its own category in a lot of ways.
Because that is the trend of adoption. More people are using Go who also use Perl/Python/Ruby than C/C++/Java. It was originally targeted at the latter, but the actual result was from the scripting language set.
I am one of them - have used (and still use) Python since v1.52, but found Go an excellent option when performance / concurrency was needed.
No I mean languages compiled to machine code. I guess that happens sometimes with JIT or with some implementations of these languages? In general Java and C# are run on top of portable virtual machine layers, right?
This is a very nuanced issue. The reference implementation of the JVM for instance will most assuredly compile some code to machine code, but it does so JIT. The developer/build server compiles to byte code that is run on a VM layer (though the distinction between the VM and a Run Time like Go's seems blurry as well).
That even leaves out Java compilers that skip the JVM step.
I just wish Go would let me compile and run with a flag -allowing- unused imports. I find myself wasting a lot of time hunting down unused imports or variables and commenting them out.
Maybe that'll be a non-issue the more I use Go, but so far it's a bit of a time waster.
To explain to those who may not know what's going on here:
Go forbids importing modules that you then don't use in the source code. This is particularly annoying with the "fmt" module, which contains things like Printf that are useful for debugging, but you may only be using fmt.Printf for one debugging statement in the code. Consequently, if you're developing, and you're adding and removing it over and over you also have to add and remove it to and from your import list over and over, which is very annoying since it's likely to be relatively distant from your use location, and it's mandatory that all imports are listed at the top of the file. (So, you can't do what you can do in perl and say "use Data::Dumper; print Dumper($debugging_stuff);" all on one line, without even being concerned about whether Dumper may already be imported.)
goimports is a source filter that cleans out any unused modules, and tries its best to add modules that you only reference. It's pretty good. You can confuse it if you have two modules with the same last bit of the name, but the standard library doesn't have that anyhow, and for the most part you can deal with that. Since it also runs gofmt for you on save, it's also a drop-in replacement for gofmt, which you should configure your editor to run on every save even if you for some reason don't want the goimports functionality. (Seriously. Just do it. There's no excuse not to. There's no excuse to ever commit code that was not gofmt'ed.)
If you do that, the problem goes away. Typing "fmt.Printf" pulls fmt in automatically, removing the one line removes it automatically, the import list is always accurate, and it's smart enough that if it isn't the only usage it doesn't remove it.
That said, I also strongly recommend setting up automatic syntax checking by compilation (flymake in emacs, don't know what in vim, etc), so that you also avoid the "Save -> switch windows to terminal -> compile -> get smacked in face with an error that feels stupidly persnickety" psychological torture. If the errors highlight in your editor on save or something, you go through that much less. Those who lived in the C#/Java etc world have long had this... a lot of people coming from the scripting side would be advised to pick up a bit more of the helpful tools the static side has to offer.
It's worth mentioning that the author of this tool is Brad Fitzpatrick, one of the main contributors to the Go standard library and, in my opinion, the most "entrenched" Go developer on the team. And by that I mean he uses Go to build large and practical projects on his own (See Camlistore), so he knows what the language feels like from a perspective similar to the rest of us. He's also one of the only advocates on the team for the inclusion of generics.
One of the things I love most about Go is how everything you need comes with the language, unlike many language ecosystems where you have to depend on third parties for profilers, plugins, etc.
Me too. I don't mind working in a good C++ codebase. It feels a lot safer than working in Ruby where things suffer from bitrot due to a culture of new and shiny.
When I talk to the youngsters about this exact feeling they look at me like I'm nuts. Coming from Ada/Modula-2/etc. where you put the thought in up front and if it compiled you were a long way to being "right" isn't something they get.
A lot of python shops I've come across don't use the system installed python or ruby. In python land at least it's exceedingly common to deploy a virtualenv with a separate python runtime and isolated 3rd party libs. This makes pinning your version deps easier and doesn't matter if the underlying server is ubuntu or centos or whatever.
That is true, what if in future ubuntu/centos include Go by default (which might not the version you use)? I believe then will have some GVM or similar tool to solve the problem.
Edit: As others pointed out, Go is compiled binary and does not required runtime (like JVM) so versionning is not issue. Thanks for clearing up.
There won't be a need for a GVM as Go is not a stand-alone runtime. Once compiled for a specific platform it will just run. You don't even need it installed on the server. You can cross-compile on your DEV machine and move the binary LIVE. Then it just runs. It doesn't need any libraries on the server.
Does Go not have the concept of linking? If you are deploying several Go applications on the same server that each use libraries, does it include duplication of libraries in every binary?
There is no linking. Each Go binary has all of the libraries it needs baked into it.
So if you have multiple different Go applications on one server, and they use some of the same libraries, then each application's binary will contain a copy of that library.
It makes things a little redundant, but also simplifies the deployment process.
edit: The only exception is if you are using cgo and liking to existing C libraries. In pure Go there is no linking.
Go applications require no installed runtime, they compile to native code. You can have no Go installed or any Go installed on the system, and the executable will neither know nor care.
Not being a Go developer I don't understand why this would be the case. Doesn't Go compile code to a binary? Why should Go even be required on the server?
Yeah, many of the ruby applications I've seen recommend RVM so that you can isolate yourself from the system-installed version of ruby. That's the nice thing about go - each application carries around everything it needs to run in total isolation from the rest of the machine.
I should just stop making assumptions about python and assume that if there's anything you ever would like to do with python, that someone has already built it :)
It's a nonsense comparison anyway. E.g. with Java I don't have to care much about the hardware an operating system (e.g. we develop on Mac and deploy on Linux).
And sure, you can use an application container. But you can also embed a webserver. E.g., we Jetty embedded and use a strict SecurityManager policy[1]. So it's more like:
Not sure I follow? With Go we develop on Mac and deploy on Linux. Just change the environment variable. Linux has some great built in tools for "security management".
There are some subtle differences.... but these would likely be exposed in almost any language with or without a VM. For example, when porting some of our Linux Go code to Windows, we realized we were renaming a file while we held the file handle open. That works fine on Linux, and blows up on Windows. That's not really something a VM can manage for you. Similar things like "what's the canonical directory for storing your ssh configuration" is different per OS, and again, is not likely to be something that the VM will sort out for you.
I'm in the middle of porting Juju, a pretty huge Go program, from linux to linux and windows, and almost all the changes necessary are not things that a VM can help with, like "cloud init doesn't exist on windows" and "unix pipes don't exist on windows" etc.
For everything else, the Go runtime really does a pretty good job of abstracting away the differences.
One version of python on a modern linux OS? How do you mesh the default version of python used by the os with the version of python required by your application code?
Not entirely on-topic, but the mention of the various language "stacks" at the beginning of the article reminded me of something I've been wondering.
Why does the de facto standard for web apps in Go-land seem to be using the built-in HTTP server provided by net/http, or otherwise having the program server as its own HTTP server?
Most other languages seem to have converged on FastCGI or some similar model ({W,P}SGI, Rack, etc.).
It irks me a bit because I don't understand why you'd want to do it this way; it seems preferable to have a dedicated HTTP server in pretty much every way I can think of.
"Most other languages seem to have converged on FastCGI or some similar model ({W,P}SGI, Rack, etc.)."
The languages you are citing are slow enough that the scripting language would like to slice away as much of the brute web serving load as possible so the slow scripting language can concentrate its power on the real task at hand.
Go is more on the compiled side. It's not C-fast quite yet (I expect it to eventually converge somewhere around 1.5x as fast, it's not quite there yet), but currently around 2-3x slower only (and net/http is seeing a lot of direct work on it, it's quite fast now). You don't get the big win that you get with letting nginx handle the brute string manipulation of HTTP and prechewing on it for the 20-100x slower scripting language.
Also, remember that you can view HTTP itself as a form of CGI request... really, FastCGI etc. doesn't do anything that an already very multi-threading-friendly language can't do with straight HTTP. Those standards are solving a lot of problems that Go just doesn't have, and straight HTTP is actually more general and flexible if you can afford it (no problems with Nginx being unable to stream FastCGI, etc).
Well, I think one answer if that you can quickly have a running web app without another piece of software. This is an attractive quality of Node, too. In fact, if a language doesn’t have a “5 lines to a web app” demo, I consider it insufficient.
I’d posit that 90+% of apps don’t need another http server. Big apps have good reasons for a dedicated http server – unifying SSL termination, load balancing – but they are a minority.
There is nothing to to prevent you from putting nginx in front of the Go app if that’s better.
For Go, you probably don't want to use their net/http server if you will also have it doing SSL/TLS. Go's TLS implementation doesn't support a lot of older cipher suites which could be a problem for some clients. As well, it is not as hardened as OpenSSL and others (such as possibly being vulnerable to timing attacks[0]).
OTH there was no Heartbleed bug in the SSL implementation of Go's net/http. So much for hardened implementation. Secondly you can use go behind a http proxy, or even in an FCGI etc environment with minimal change to the code.
This makes no sense. The runtime of Docker is the Operating System. There's no extra layer, as it's being implied.
And there's no difference between Go and the other languages that makes Docker more or less useful. You can have separate Python processes without Docker, just like you'd have separate Go processes.
I like Go, but this article just sets up strawmen to bring down.
The question he's addressing isn't what you can do, but what is commonly being done. You don't need RVM, you don't need Docker. Hell, you don't need Rails. But those are the idiomatic layers of the stack, for a non-trivial part of the Ruby development community.
Sorry for the confusion JVM = Java Virtual Machine, RVM = Ruby Virtual Machine, PVM = Python Virtual Machine. What I was trying to point out the layers of vitalization just to run an application. Docker is yet another layer on top of the operating system (a virtual machine running inside an operating system inside an operating system possible ect).
Ah, ok. I can see where you're coming from, but I don't really think of Docker as being an extra layer on top. It's more a way of rearranging the OS layer itself along a certain axis. The cognitive overhead is similar to a virtualisation layer though, so that point stands.
Have noted this 'opinionated' trend going for quite a while, so this comment isn't about this article in particular, but can someone break down why an opinionated guide to something technical would be preferable to an impartial one? The only thing it seems to imply is that bias adds value in its own right.
It's a pre-emptive disclaimer "I know this isn't objective, don't complain about that". And it tells you that the guide isn't going to offer you confusing choices, it's going to tell you one way to do things. For some people that's an advantage.
Thanks for your reply lmm. I can see what you mean. However, I do think it has a high risk of building new dogmas without the understanding of when these dogmas should be broken.
I see value in educated opinions. For instance a while back I was trying to figure out how to make a web app in Python (keep in mind that, while I can program, I have zero knowledge about web things). This is what I saw: https://wiki.python.org/moin/WebFrameworks
Which framework is the best? Why are there so many? Which is the easiest for my specific goals? An opinionated guide that said something like "Use Flask because X" or "Use Django because Y" would have been pretty useful.
Beginners guides are a special case, the main focus is in getting something working with the minimum of fuss that you can understand. I do understand that expert opinions can help build confidence, but perhaps it's even better to explain matters clearly so you can make your own opinions.
I mention this because the article acts as if getting rid of abstraction layers between the OS and the code is a new idea. No, that's how all compiled languages are... that's the point of compiled languages. I suppose Go's most common use case lines it up against a bunch of slow interpreted languages, but really there's no reason except good libraries that you can't use the other compiled languages I mentioned for web apps.