EDIT: I must highlight the point about checking lot of boxes. In many discussions about features of programming languages, we get responses like, "language Y does that too. Why not choose that language?" Well, because we don't pick languages for one specific feature. We pick them for the combination of features.
I still don't get the Go love.
That being said, if I were starting a web service as a business today, it would be very hard to persuade me to not choose Java. It's simply the best platform from a business perspective. For better or worse, CS departments across the US produce Java programmers more than anything else. This makes it very easy to hire Java developers. Java has stability, Java has concurrency, Java has hot reloading, Java has a good track record, Java scales, Java has really nice functional programming support, and Java is very popular with the everyday programmer. It Java has so many benefits outside of it's technical or philosophical specifications, that it's almost an obvious choice to me for web.
What's funny is that Erlang is the ideal platform for me from an idealist perspective, but I don't think I have the luck or experience it takes to successfully start an internet company with Erlang.
Take interfaces. In Java you might start with them. In Go - in the best case - they emerge, when it's time for them. Java has more mature tooling, but then, I cannot remember gathering runtime insights with Java quicker than with Go pprof[1].
Java is rock solid and more and more libraries are written in lightweight and clean way. Go has more momentum and also a growing number of curious users, who explore the language in creative ways[2].
[1] Google image search for "go pprof": https://goo.gl/6l7t1b
[2] Just discovered this amazing guy recently, https://github.com/fogleman/ln, https://github.com/fogleman/nes
JVM suffers from slow startup times and tends to eat a lot of RAM, even when the app doesn't technically need it around. It has an object model that spawns a bazillion tiny objects, and much of the JVM's GC design exists to cancel out those tiny object allocations.
JVM has many upsides (the portability and pluggable nature of JAR files is a huge one), but I think a lot of people are attracted to Go's bare-bones approach. Closer to the metal, a "better C", smaller overhead.
Finally, the object-oriented nature of the JVM is sometimes a pain. This can be worked around, but there is something to be said for preferring the typing of Go.
For those benefits you trade off vs the jvm a) abysmal tooling b) extremely primitive concurrency support c) a more primitive type system and d) a much smaller ecosystem.
I very much like golang for 2 classes of problem 1) http/s based microservices and 2) command line programs that are a touch more complex than bash. I would never choose golang for a system that I thought was going to have a high LoC count or had a complex domain to model.
Go just works better for some of us, and that's all the justification we need.
I also find the tooling for go vastly superior out of the box compared to what i end up using with java/Scala. XML?! Wtf?!
Go forces people more into boxes and leaves a lot less up to discussion. This is annoying for the individual contributor, but I believe is a net plus for a team of contributors.
Much of the Go love comes from doing (almost) everything Java does with a lower cognitive load... and goroutines are really useful, too.
Golang fits in nicely in such cases. If I want the JVM, I rather build a clojure'ified uberjar.
Debugging absolutely needs work though.
Other than that competitor, I don't think Go has too many others in the same niche. Maybe D? I love the combo of native code + high level language + single binary in a language that also tackles parallelism.
It's as if the Go language designers took a good hard look at Python and went "This is what's wrong with it", taking its greatest weaknesses like dependencies/packaging and the GIL, turning these around 180 degrees, instead becoming main advantages of their new language. Of course, it's not an interpreted language so the comparison isn't perfect, but Go ticks a lot of boxes for me as well that Python perhaps never will due to design.
Only in that it will end in a native binary.
In any other sense Go is worlds behind.
What is that even supposed to mean? The semantics and memory model are nothing like C and the syntax even less so.
> generates a single
Just link against static libraries; it's literally a single switch.
> supports concurrency very well
Better than C; much, much worse than C# and I'd argue even worse than Java with j.u.concurrent (want channels? use j.u.concurrent.BlockingLinkedQueue)
Opposite example: implementations of OOP in Lisp and JS.
Genuine question, why all the negativity?
Have you used delve? https://github.com/derekparker/delve
Go makes it easy for third party applications to parse the language,so generics are possible with pre-processing/codegen; e.g., https://clipperhouse.github.io/gen/
For me the big minus of Go is that it is memory unsafe language when it runs with GOMAXPROCS>1 (default since 1.5). It is not that bad like in C as opportunities for bugs are not common, still this is an issue as consequences of such bugs is arbitrary code execution.
Another problem is lack of union types leading to poor code practice when those are emulated through (foo, err) or similar return types.
No, it can't. There are patterns that no monomorphization strategy (including code generation) can express. For example:
func MakeList<T>(x T) List<T> {
...
}
func Foo<T>(x T) {
if ... {
Foo(MakeList(x))
}
}
This is a contrived example, but this shows up from time to time in functional data structures.The reason I will almost never use Go for web apps is because interaction with databases is limited (almost entirely) to raw queries. Maybe I'm spoiled by the likes of Active Record, Sequelize, Mini-mongo, Sql-alchemy, etc, but it's a huge drop in efficiency to spin my own SQL.
The point to take away here is that Go, more so then many other languages IMO, has its strengths and weaknesses. If you use Go in one of it's weaker use-cases you're gonna have a bad time. If you use Go for one of it's strengths you're gonna have a great time.
See you guys and gals in n weeks when we need to rehash the pros and cons of Golang again.
Sorry, I have to disagree. I come from PHP, where when you sneeze an ORM appears. I actually am a DBA also. I am very familiar with SQL and I love writing out raw SQL.
I don't see this as a limiting feature. It doesn't affect me at all.
There are ORMs for Go as well. But I don't know how good they are. YMMV!
Last point. I have shipped into production a web app using GIN framework. I ported from PHP to Go. I didn't feel I was losing anything.
Go is amazing. It hasn't let me down yet. I doubt it will.
My previous job did a PHP -> go transition. I felt like it went well.
YMMD.
There are plenty of ORMs and query builders available for golang, many of which have a very similar interface to AR. I personally use a query builder and let structs be in charge of reconstituting themselves from the db rows returned, and am quite happy with that tradeoff, in fact I prefer it to having objects magically instantiated behind the scenes as in AR. There's no need to restrict yourself to raw sql if you prefer a query builder of some kind or even an ORM (if you don't mind using reflection).
Little discussion about the release changes happens...a simple google search will return all the discussions of pros and cons you would ever want to read in a life time...
Sequelize was a huge drop in efficiency for me any my team. As soon as you go outside of the typical select-where statements, it completely falls apart. I spent hours manipulating that horrible "almost-SQL" syntax to get it to spit out the query I wanted, and often I would just give up and fall back to using a raw query. Yeah, it's great that you can use raw queries when you need, but I soon realized that I almost always wanted to use them.
I switched to KnexJS which has syntax that is practically one-to-one with SQL and have had very few problems since then. Generated queries are much more predictable and easy to write, and it forces you to improve your SQL skills. I view that as a good thing.
Doing things a bit lower level with beautiful standard libraries is OK. In subjects like html parsing, templating, routing or intercepting requests it has a meaning. You learn dynamics more down to the metal. However raw sql and value mapping with NullString etc. doesn't give the same joy. Maybe a higher level standard or additional x package can solve this problem.
https://www.reddit.com/r/golang/comments/46bd5h/ama_we_are_t...
https://www.reddit.com/r/IAmA/comments/46asrt/we_are_ok_go_w...
Am I being stubborn in my longing for an npm, Ruby Gems, or pip? Is there a reason why one of these hasn't emerged/been adopted by the community? (I'm aware of the 1.5 experiment with vendoring.)
Semver and pinning versions has always just made sense to me. I can easily adopt new features and fixes automatically without worrying about things breaking.
How does the community feel this far along?
Personally, I believe package management is one of those things that really does need an official blessed solution. Otherwise, you have a nasty bootstrapping problem: if there are ten competing package managers, how do you install them, and how do package developers know which one to put their packages in?
Collection types have the same problem. You basically need to put some collections in a blessed core library, otherwise it's virtually impossible to reliably share code. Any function that wants to return a list ends up having to pick one of N list implementations and which ever one they pick means their library is hard for users of the other N-1 lists to consume.
The Go team hasn't blessed a package manager, I think, because it's not that relevant to them: they mostly live within Google's own infrastructure which obviates the need for something like version management. They probably don't feel the pain acutely and/or might not have the expertise to design one that would work well outside Google.
It's not a package manager per se — Go doesn't have a package system with manifest files like RubyGems and NPM — but it does manage dependencies in the same way, with versioning constraints and lock files.
That said, my time in golang has crystalized something I'd been leaning towards anyway, that is dependencies are way more dangerous than we think they are. I find all of my code now (golang or otherwise) less likely to have dependencies, and therefore dependency management weaknesses are mitigated (not solved).
There's just something about the ecosystem of dependencies. Most of the deps I use are considered to be done. They are simple, small, and orthogonal to each other.
Maybe it's because of the convention to make your library implement interfaces defined in the standard library. Maybe it's some kind of ingenious magical feedback loop where, since there is no package version manager, authors are encouraged to write once and then publish finished products instead working on overreaching and interconnected packages that get API changes every month. Therefore alleviating the need for a package version manager.
My point is just that I wouldn't want people who are considering Go to immediately write it off because of the lack of a standard dep version manager. You can lock dependencies with godep. Or you can check in your dependencies to your project's source control. Either way, even though it's unconventional, it most likely won't be a problem.
What Go is lacking at this moment in my opinion is:
1) A comprehensive and mature web framework. Play w/ Scala is my go-to choice now, with Django a very close second.
2) A decent cross-platform GUI toolkit; heck, I'd settle with Qt and/or .NET bindings for Go. The power of Go is statically linked binaries, and I think the area of desktop applications will be easy to target if a good solution emerges.
I completely agree here. GIN is my fav framework so far, but it falls down sometimes on documentation and also on features. A lot of features.
I know there are three viewpoints with Go.
1) Use net/http and just import libraries.
2) Use a "lightweight" framework if you must, just import libraries.
3) Use a "full fat" framework and get to work on the app.
I would love to have something like where Codeigniter was for PHP. An MVC framework where you could just write code, it was lightweight and had the best documentation for a framework out there.
Now if something like that was out there for Go and actively maintained. I would be all over that!
A bit off topic: why isn't there (or is there?) an easy way to view all your starred repos on Github and search through them?
1) Go produces 100% portable code. I absolutely suffered doing the same for a very basic C++ program that used C++11's std::regex. Compiled fine on clang-3.5 on OS X, fails on clang on Linux. It took me hours of searching online to find and install the exact version of GCC that actually fills in std::regex instead of just keeping it empty. Trust me, there are some versions that do that! No errors during compilation, but still doesn't run.
2) Statically compiled binaries. I can be confident that the absence of some essential library from the user's end won't break my app.
3) Cross-platform, especially with something like Qt. Write once, compile for each OS, then run - done!
On another note, because writing programs in Go is much faster than say C++ or C for most use cases.
Call me old fashioned, but I've only ever used the stuff from Gorilla (mux and sessions) and before that plain CGI with Go, and running behind uriel's cgd to hook it up with nginx.
I've never been fond of web frameworks that try to hide a lot of stuff from you.
if err != nil ...
I know you can do if ; err!=nil but that not that much better and you end up in deeply nested if blocks.
i have to mentally block out err !=nil to read any gocode linearly. How is this acceptable, I don't get it.
https://blog.golang.org/errors-are-values
We recently scanned all the open source projects we could find and discovered that this snippet occurs only once per page or two
This seems false from my experience, def way more than 1 or 2 instances per page.
try:
x := blah()
except Foo:
yadadad
which is worse (IMO) than x, err := blah()
if err != nil {
yadada
}
Besides the extra syntactic clumsiness, it was really hard to know what was going to throw exceptions, and which exceptions, and when. Frequently I would get bugs from unexpectedly thrown exceptions.You said "I have to mentally block out err != nil to read...code" -- for me, the error handling code is code, code I want to pay just as much attention to as the non-error path.
So for that reason I really like Go error handling.
For a client-side script or something, maybe this isn't true; feel free to use log.Fatal or panic if that makes sense for your use case.
You likely want to pay as much attention as required to make things work, but the purpose of your code isn't to generate errors -- errors are what get in the way of the actual purpose of your code.
For people who want to get an overview of what some code does, the error code is interesting only after you understand the actual purpose, and sprinkling the error code throughout the code that describe the purpose of the program causes distraction.
and you don't need massive if blocks, you can use more early returns as part of the err checks.
Here is Erik Meijer talking about golang exception handling
https://www.youtube.com/watch?v=a2ihmMmSfwk&t=577
The golang guy doesn't answer the question properly and repeats "exceptions are not for control flow". Really disappointing answer and cringeworthy interview.
Still can't get over the moment I realized that in order to deploy my web server on an empty virtual box all I had to so was to build and upload. After all the languages and frameworks that required endless customization and setting up it was a true eureka moment.
For example, when I create client-server projects, sometimes I put both client and server under the same git repository, in the same folder (whether it is a good or bad decision is another discussion). $GOPATH forces me, therefore, to put a client project in the $GOPATH tree, and this just feels ugly.
Of course, you can change $GOPATH per project, and I end up with `export $GOPATH` in makefiles, but this is rather ugly too.
1) Supposed I have a library that was written in C that receives a security update which is used in a Go program. Under what conditions do I need to get a recompiled version of the Go program.
2) Supposed I have a library that was written in Go that receives a security update which is used in a Go program. Under what conditions do I need to get a recompiled version of the Go program.
3) Is there a way to tell from the binary that the program was written in Go?
Trying to figure this out for my Sys Admin dealing with Vendors role.
$ cat homedir.go
package main
import (
"fmt"
"os/user"
)
func main() {
fmt.Println(user.Current())
}
$ go build homedir.go
$ otool -L homedir
homedir:
/usr/lib/libSystem.B.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 0.0.0, current version 0.0.0)
2) You (most likely) have to recompile and re-deploy the downstream Go program with the patched library.
3) Not sure.2) Always.
3) Yes, Go runtime is linked in to executables build with Go.
Given a lot of software makes it to my door written by government contractors for grant management / compliance, I don't have the source code.
Complexity isn't free. Java might have and abundance of tools, IDE's, language features etc, but you can't claim that matching up every Go feature or tool with something superior found among the huge Java universe makes Java superior in every way.
I find that there is an unfair assumption being used by the Java advocates, here which is that every software developer has a deep knowledge of Java.
As one of those people who can certainly write Java code, but who is not familiar with the Java eco system and has not spend a lot of time with I must say that Go to me is a clear winner.
My exposure to professional Java development has been quite frustrating compared to writing Go code. Every Java project I have gotten has used some different built tool: Ant, Maven or Gradle. They have also all seem to use different IDE's. The complexity of each of these tools is staggering. Considerable time has to be spend learning these tools.
Go in comparison is laughably simple. You can get productive in less than a week without ever having used the dam thing. The tools and the libraries are very quick to get into. In fact I find Go code so easy to read that although I am an iOS developer by trade, I frequently read Go code to understand how various algorithms and network stuff works.
An organization would easily be able to add people to a Go project without much previous exposure to the language. Adding people with limited Java knowledge to a Java project however would be far more expensive. Considerable time would be needed for training.
There is a lot of money to be saved from having a well thought out standard library combined with a simple language with simple well thought out tools.
As a Swift/Objective-C developer, my major gripes with my development process is actually the complexity of the tooling. Both Swift and Objective-C are fairly straightforward languages IMHO. In this regard I greatly envy Go developers although I do enjoy the strong typing and generics in Swift.
I went with Go because it was easy to use and understand. I could read other people's code easily( Even with a large code base, I have never found myself scratching my head trying to figure out my own code does), could set up my workspace in less than a minute and all the text editors I used (sublime, Atom, Vim) supported it. I Don't really care about the fancy IDE's. Just syntax highlighting and code completion is good for me.
I started learning go on September 2015. And I have managed to implement the porter stemmer algorithm and an inverted index in it. Miss generics but LOVE interfaces. The fact that any concrete type that implements method 1 satisfies interface 8 is awesome. You can easily reuse code from different package without changing anything.
Notably new this time is transparent http/2 support and tighter rules for integration with C.
0. could lto optimize or link against a shared library to reduce the titanic size of compiled programs and cut down on duplication of instruction. Therue is no practical sense in wasting memory and storage on systems with dynamic linkers: edge cases of including the world for rare situations but YAGNI in real production systems.
1. could output flat binaries and self-host runtime (panics) for practical kernel development in Go
2. Generics (both types and immutable constraints), I think C++1z has the right approach to this (and constexpr and constant arrays are nice and are able to provide more hints to the compiler).
I also wonder why Go wasnt developed as an IR compiler / llvm frontend, because it would've levered an existing debug and portability ecosystem with much less work.
1. What do you mean self-hosted runtime? Anyways, golang will likely never be a good candidate for kernel development, but in theory you could do it (go supports assembly)
2. Generics would be nice. Who knows, maybe they'll be in 2.0?
Go wasn't developed in llvm, because they wanted to build something very fast, and they were planning on writing the compiler in golang from the start (so that it could be part of the libs). Also having your own scheduler kind of breaks debugging, you can build go programs with gccgo, but gdb doesn't work because it has no concept of what a "go routine" is. Delve (https://github.com/derekparker/delve) will eventually fill the hole of the missing debugger, imo.
Edit:
Formatting
Oberon, AOS, EthOS, Singularity and Midori projects prove otherwise.
Go just needs an OS research PhD student proposing "Goberon" to their tutor.
There will be no 2.0 and there will be no generics, at all.In fact there will never be any changes to the type system, cause it's impossible at this point.
However, the _language_ doesn't give me much programming pleasure alas. Since there is plenty of time for Christmas, here's my syntax wish list :)
'?': C's if-then-else operator.
Block-syntax for closures ala Ruby. Unifying blocks and closures makes creating DSLs easy, but doesn't add to cognitive load (no more than using anon funcs)
Pattern matching like Scala, ML, Rust.
Sum types -- (Yeah, I lied. Not just syntax enhancements), or at least discriminated unions. I'd like to see an example (in the FAQ entry on the topic) on why support for it is troublesome.
For 2017 Christmas, -------------------
Macros ala Nim.
Systemic support for Goroutines, including detection of conditions where a goroutine would never get scheduled. Erlang-like tools for built-in goroutine insight.
------
My ideal language would be an intersection of Nim+Go
Pattern matching doesn't work well without sum types.
So don't hold your breath.
"Hello gophers,
We just released Go 1.6.
You can read the announcement blog post here: https://blog.golang.org/go1.6
..."
That said, there were a few points I noted, based on a recent go I gave it (pardon the pun), at least in relation to my style of development for this project:
1. It's hard to tinker, mostly because it's fussy about what variables are defined or used. This is a strength in the usual course, but when one is trying to posit what a poorly documented 3rd party API is doing it can be a serious pain.
By tinkering, I found that I often had to comment out or uncomment lines, or handle or ignore errors. There was a lot of flipping up to the beginning of the file. I would spend so much time fiddling with the lines that I would at times forget what I was even trying to do.
I might just have memory problems, I acknowledge. :)
However, what would make sense is a go "mode" where it runs in a non-strict way, with what would ordinarily be errors being warnings. A "tinker" or "whirl" mode, so to speak, that softened the requirements so one could get a better sense of what was happening before committing to a design.
An interpreter mode might also be quite valuable, to address this problem and the ones below.
2. Error propagation - I see the point of errors being returned and the lack of a "throw/catch" style, and its benefit, but I feel it's a lot of typing for marginal gain. I usually end up with an error propagating a set of strings that ultimately conclude as: "Database error: transaction error: processing error: http error: reason", which is to say: equivalent but less information than a stack trace would give. I see the mandatory error acknowledgement simultaneously as a strength and a waste of time, and I admit being on the fence about it.
3. The next point I am not on the fence about: Debugging. It is not apparent how to get a stack trace, and the best option looks like including a third party application that generated errors. For the obvious and reasons below, this is a problem.
4. Package management: This was fussy and could be time-consuming. It is not apparent to me why one needs a GOROOT and a GOPATH. I think Python's virtualenv gets it right, by comparison. A second but related problem is package versions. Maybe I'm missing something, but making sure you get the latest semantically equivalent version (in the semver sense) was not apparent.
5. Package debugging: If you include a 3rd party package, and it's broken in any way, it's a veritable quagmire to identify and fix the problem. My experience was that the best way to debug a third party package was to block and copy all its bits and then debug it as a local source in your own. Obviously this is bad for a long number of reasons, and I might be missing something, but no more apparent option appeared when I investigated on how to tell what is even happening inside third packages.
6. Automated testing: I've not seen a test runner that reloads when source files change, particularly one that might be used with goapp from AppEngine, meaning go auto-testing can be quite a bit of patient thumb-twiddling as the binary reloads.
Which is all to say that there are some concerns about developing a larger project in this language, particularly if there is quite a bit of complexity that needs lots of testing or potential debugging and/or inclusion of many third party packages.
I've not reviewed the 1.6 notes, so perhaps these are addressed to some extent there.
In any case, none of the issues above is insurmountable, and overall I give the Go design a lot of credit for experimentation and interesting choices, but the issues I've seen above give me pause before committing a team to the language – for the moment.
As for (2), I feel it's more of a consequence of programmers not using error types to its advantage. Since Error is an interface it allows for an absurd amount of flexibility (e.g. bundle up a whole bunch of information into one error and send it back) and typed errors, both of which are excellent for testing and debugging.
As for (3), I usually rely on printing output (github.com/davecgh/gospew is quite useful). To get a stack trace just calling panic() in the offending code area will suffice.
No arguments on (4) - it could be better - but I think support for vendoring is a good step, and the maintainers seem to be taking it slow and getting it right.
On (5) -- if you go get the package it's available in GOPATH and/or it's usually vendored, so you can just go edit it in place (including debugging statements if you need more insight) without needing to know any magic $X_PATH rules -- I see this as a huge advantage. Furthermore, go get-ed code is each in its own version control repo, so sending patches back upstream is (generally) easier than ever.
Anyway, hope I don't seem argumentative (everyone has different tastes), but maybe some of these suggestions might help you a bit with your language peeves.
On (1) Great suggestion, looks good.
On (2) I'm probably biased by having spent a lot of time with Python and Javascript and bound to some preconceived notions of how one should deal with exceptions, so perhaps I give Go a harder time than I should for my failings and not its. :)
On (4) I hope they get it right; packaging can definitely make-or-break the system.
On (3) and (5) I found these techniques could/did-not work when testing Go App Engine. Editing the third party source had no impact, even after restarting App Engine, re-running tests, and deleting the .a files. I'm sure it's just another trick, but I couldn't find it so I eventually just gave up ... hence it being in my list of concerns.
Thanks for the feedback, I appreciate the suggestions.
Cheers
It's so damn arbitrary, though; it refuses to let you have unused imports (which is not a source of bugs) but will happily allow you to shadow variables (which is a serious source of bugs) without even warning you. Super weird.
You may have to leave off that last argument for your own sanity. I found that 'shadowstrict' drives you mad at first, but you end up making better code for it -- mirroring my general experience with all the things about go that annoyed me at first.
In addition, once your workspace increases in size, GOPATH becomes a mess in my opinion.
iirc the workflow with that is change a file and process will rebuild and test it.
Personally, I prefer to write code in a functional manner. While I've always thought Go looked like an amazing platform for programming in general, I haven't been keen on moving to another imperative language.
It seems the landscape for functional alternatives are mainly Scala and Clojure which are both based on the JVM and require a bit of time to learn the tooling. I am not a Java or JVM export, so I haven't been too inspired by this either.
Cannot talk about functional alternatives without mentioning Haskell. OCaml (when abstaining from the "O", as many OCaml'ers do; similarly Scala'ers often abstain from the "O" in Scala) is also an interesting option.
Finally there's Rust, which is besides being a bit more functional also more low-level than Go.
While being fairly young, Frege[1] also deserves a mention. Very similar to Haskell, but on the JVM.
I had forgotten about Rust. Are there major projects being used for this yet? I've heard it's picking up quite a bit.
A google seach show that you could build for NaCal in Go 1.3 but only run it in special builds not Chrome itself.
Does anyone know if that was included in this release?
That seems a little bit distasteful.
Edit: Blog post up: https://blog.golang.org/go1.6 maybe change the article link to that?
Mods, maybe change OP link to this?
if/else:
if i == 0 {
return "foo"
} else { return "bar"
}terany:
return i == 0 ? "foo" : "bar"