250 comments

[ 4.0 ms ] story [ 270 ms ] thread
Offtopic: Can we please use "GoLang" for the language, so we can use "Go" unambiguously for the game?

Especially in titles, where there is little context.

For the game we should use "Go/Baduk" or something like that.
"game of Go" seems simple enough...
i would argue that for most people here Go = GoLang

i had never heard of the go game, before the ai go thing

I don't know what the basis for your argument would be. Go the game and GoLang are both fairly talked about topics in Computer Science, most programmers do not program in GoLang (according to Github), and the AI match was a big deal for Computer Science in general. I would not be so quick to say that for MOST people here Go = GoLang, and agree with the parent comment.
Just because most programmers don't actually program in Go themselves, it doesn't mean they don't know what it is.

I haven't written a single line in Go, and yet it's immediately obvious to me what the title refererred to.

You have multiple people here telling you that their first reaction was not Go as in Lang. The obviousness to you and others does not prove the title is unambiguous to most. Here, we're trying to propose a solution that aims to eliminates ambiguity for the majority.
I believe we are still in majority. Nothing has proven otherwise
The majority in what I said is = [people who treat Go as GoLang first AND Go as the game Go first] = the set of all people reading hacker news minus those who don't know either Go. Writing GoLang removes ambiguity for this majority. My first comment on this subthread has shown that neither you nor any other poster has proven that Go = Go first for most. Nothing you or any other parent comment including my own has proven either of Go = GoLang first OR Go = Go the game first for the majority of people.
It depends on the context, too. If I read a headline saying something like "Go is awesome for your brain", I'd be 95% sure it refers to Go the board game. When the headline reads "Why everyone hates Go", I'm pretty sure it can't be about the game. I don't think I'm being an exceptional individual - humans in general are very good at taking hints from context.
I do find the name extremely unfortunate. It's impossible to search for, as "go" is an extremely common word (bad for search engines) and substring (bad for ctrl-F find). I tried searching for shared web hosts that provide Go support and just gave up. Kind of hilarious to see a first-party Google language be impossible to search for.
A great many programming languages aren't particularly searchable, especially when searching engines weren't up to todays standards yet. Things have improved, but I remember the dark days when looking for anything C# would shower you with C-related links.
Or how about searching for ".NET"? :)
It should be illegal for programmers to name anything they created ;)
Using "golang" instead of "Go" nearly always gives the correct results in my experience.
That's true-ish, although it seems unlikely that most marketing departments who would be putting together a web server page would use "golang" over "Go".

Edit: This would be solved if the language was called "golang," which is precisely the original poster's point.

That's like calling for people to specify "Microsoft Windows", to avoid confusion with glass-enclosed wall openings.

I know there was a bit of news recently about a game engine defeating a top-level human player. Beyond that, however, the notion that "Go" references on Hacker News should default to the board game rather than the programming language is absurd.

Articles about windows-the-opening are pretty rare here, so "Windows" isn't ambiguous. Articles about Go-the-game are common, so "Go" is.
Good points, and also correct answer. Identity is hard to question. But when you try Go without prejudice, it's just fun (and productive) afterwards.
With golang, it is incredibly easy to get productive fast. It's like modernized, safe C with good standard library and trivial deployment. Those are pretty good selling points for getting stuff actually done.

Using Haskell for similar stuff is more tedious, even if a actual coding is more fun. I can see (and sometimes feel myself) the cognitive dissonance here.

I think the issue here is that you're comparing Go to C and Haskell.

C is decades old. Haskell was designed to help you write correct programs, rather than simplicity of use or productivity (or that's how I'd characterise it).

If you compared Go to C# or Java 8 or Scala, it'd probably look a lot worse. Deployment isn't so difficult that Go has any advantage in my experience: install a JVM on the server, ensure your build system is producing a fat jar, run it. Done.

With Capsule you can even make self-executable JARs that have a little shell script attached. Then you can run the program like any other UNIX app. chmod +x and ./execute it. Fully self contained, and can even update itself automatically.

I use C# at work, and I use Go at home. I really do like C#, but there is a reason I am using Go at home. I find I am more productive, and can develop better code faster with Go even though I am very new with Go.
I'm curious which parts of Go you find more productive than C#. Visual Studio slows you down?
> Using Haskell for similar stuff is more tedious, even if a actual coding is more fun. I can see (and sometimes feel myself) the cognitive dissonance here.

I don't think the same could be said for say, Scala or F# which offer many of the same paradigms but in a more flexible way though.

I work in Go full time, so i don't know if that counts as without prejudice. But I do not think it is fun or particularly productive (if measured by the amount of stuff i can get done in a particular set of programming time). I'd say I haven't used a language I was less productive in or that I enjoyed less since Java 1.

What I think Go has done for me, is crystalize a belief I was already leaning towards, which is that a language being productive or fun is a lot less important than standards cutting through the issues that don't matter.

Not arguing about the best way to format code, or which test library to use, or how to share memory across threads is what makes Go valuable. It is implied that the language has to be this bad to achieve that, which is the open question to me.

I don't hate Go. I do strongly dislike posts with clickbaity titles that have an admission the title is wrong in the very first sentence.

The rest of the article is little better. It can be summed up in one line: People who dislike Go are upset because they incorporated their favourite programming language into their identity, and the success of Go challenges their own choices.

Although I don't hate Go, I also don't like Go much, but it's not because it challenges my identity. I am not a Haskell or Scala programmer. I've used a whole bunch of languages in recent years, none of which are especially clever. I dislike Go because I agree with the criticisms of it and I'm afraid I might end up having to maintain code written in it one day. That wouldn't be much fun.

Fortunately, so far I've been able to avoid maintaining PHP or COBOL so hopefully my luck will hold and I'll be able to dodge Go too.

(comment deleted)
If that's an accurate summary (I am not commenting on that fact), it's a completely clickbaity summary. Because it applies equally to why everyone hates every even semi-popular language (other than their one true love, if it's considered sufficiently popular).
For a one line summary, it's pretty accurate, but it's also a great illustration of why basing opinions on one line summaries is often a bad idea.

The difference between Go and pretty much every other semi-popular language is that Go is very much defined by what it isn't rather than by what it is. In that way, its success is an implicit criticism of other languages much more than the success of any other language would be.

What's worse, is that it's a criticism backed up by empirical data. But programmers are unique and lucky, in that they get to be illogical and dogmatic while getting to appear rational and technological.
I am not agreeing with your sentiment for Go but I do want to strongly agree with this statement:

> I'm afraid I might end up having to maintain code written in it one day

I have similar fears about Ruby. This is also true of many contractor firms where they write beautiful tested code which is designed to work really well right now, but not designed to last (think views rendering database objects).

I think this is a sentiment people need to have when they see something cool or some sort of solution: Will I, in 4 years, want to maintain this? Will some person, in 4 years, curse my name for having written this?

I think python is going to keep eating ruby's lunch as more universities teach it.
I agree the title's a bit baity.

But this part stuck out for me:

> When I first heard about Go, I thought "What? No exceptions? Pass."

Lo about 12-13 years ago I balked at Python's significant whitespace, but I came around. And rust's lack of exceptions, but I'm coming around. I think there's certainly something to be said for "identity" (maybe it makes more sense to describe it as prejudice/bias/context, but whatever).

I haven't given Go a fair eval yet so I can't say much (except I don't "hate" it.)

"I dislike Go because I agree with the criticisms of it and I'm afraid I might end up having to maintain code written in it one day"

and:

"I also don't like Go much, but it's not because it challenges my identity"

You are EXACTLY who the article is talking about. One of Go's selling points is maintainability. Go's inherent bias towards maintainability challenges your identity.

Selling points are not facts, they're just arguments people who are trying to sell something like to make.

Go's users and designers make all sorts of claims about it. As it happens, I've evaluated them and find that I often disagree with them.

For instance, Go projects often don't specify the versions of their dependencies and choose to just clone the code into their own source tree instead - if you're lucky. If you aren't then the project simply depends on whatever is found in the dependencies git master branch. I find this to be poor practice from several perspectives, maintainability amongst them.

"Selling points are not facts"

except when talking about maintainability, you are not talking about facts. Show me the "fact" that Go is hard to maintain.

I never said code written in Go is hard to maintain. I said I don't want to maintain it, because I don't want to debug or write Go myself. You're arguing with a straw man.
the article is suggesting that when people say they don't want to debug or write in Go is because it challenges their previously formed beliefs in what they believe they need from a language. The fact that there may be another way or that projects are increasingly succeeding, challenges their identity.
Counterpoint: Show the fact that Go is easy to maintain.

The language is, honestly, too young to have much "rubber meets the road" legacy code for anyone to make a strong evidential case with. It's all theory until a decade from now.

The burden of proof is on the people making the "selling points" to prove that they are true -- in this case, if the Go community claim that Go is easy to maintain, the burden of proof should be on them.

(Note: I'm not arguing for or against this point; I've never used Go, so couldn't possibly know)

Isn't that fairly subjective? Some people find Lisp hard to parse and therefore to maintain but that doesn't mean it's inherently unmaintainable.
Yes totally subjective - different people work on different projects which eventually opinions are formed from.

I don't think Go was intended to improve upon any Lisp deficiency.

If the engineer who wrote the code understood the problem well and was a decent engineer, then the code will be maintainable no matter what the language is. Understanding the problem well is very rarely achieved.
The issue is not "is the code maintainable" or "does Go lead to unmaintainable code".

The issue is, do I wish to spend my days debugging code and writing more code, in Go? I used languages with Go's limitations back in the 1990's. I don't want to go back.

Writing and debugging code in Go is extremely more pleasurable than debugging, say, python. I write Go all day while our data scientists write python. Unfortunately python gives those guys enough rope to hang themselves and me too. It's simply harder (not impossible of course) to write unmaintainable code in a limited, static language like go.
Yeah, I wouldn't want to maintain a large Python codebase either.
Python in a nutshell: What you gain in flexibility and terseness, you more than lose in needing 100% unit test coverage, because every line could fail to execute (with an error that many other languages would find at compile time).
(comment deleted)
I don't dislike Go. I just think there are zero use cases where Go is the best choice. But what I do dislike is when people try to hype and con others into adopting a language to justify and increase the return on their own time investment.
> But what I do dislike is when people try to hype and con others into adopting a language to justify and increase the return on their own time investment.

The same can be said of any programming language community, IMHO.

True. This is why I find the point of the post kind of "backward". I don't think most people hate something because they feel attacked in their identity. I feel like it's the opposite: most people defend a certain technology at all cost because they feel attacked in their identity when somebody criticizes it.
Sure. I think it's more prevalent among Go zealots, probably because so many were lured into it by the inital hype, but it's not at all Go-specific. Another example is the hype and love-hate relationship people have with Javascript MVC frameworks. Even with React, which actually deserve the hype, there are many who default to "hating" it because they're sick of being fooled by all the hype.
Bad code is bad code regardless of language. Some languages just make writing bad code more palpable than others.
>Obviously, not everyone hates Go.

Well, at least the author saves me the time reading the rest of the article.

ML is also simple, pragmatic and from the '70s.
``Go is not meant to innovate programming theory. It’s meant to innovate programming practice." – Samuel Tesla

http://go-lang.cat-v.org/

And as usual, http://9front.org/who/uriel/

People who dislike X are upset because they incorporated their favourite Y into their identity, and the success of X challenges their own choices.

True for football teams, political parties, games consoles, superhero franchises, religions, food choices, colour schemes, preferred spelling variants, ...

Sometimes, sure. But none of those are our jobs (except if you are a football player, politician, etc).

Computer programming languages are our jobs. It's okay to have preferences. I (a full time front-end webdev), think Python is probably the best language out there. But it doesn't define me, because that's just silly.

I agree that a language doesn't define you but what I wonder if a person's favorite language has some correlation to certain personality traits. I would be lieing if I didn't say I get more enjoyment from some languages where other people don't. Perl vs Python for example, pythons core values are to try and make it only one way to achieve something, whereas Perl tries to give you multiple ways to achieve something. I would guess that Perl may appeal more to artistic people and Python would appeal to more engineering type of people. This isn't a claim, more just something I think would be interesting to investigate.
Ok, I write every day in Rust and JavaScript (and not just jumping monkey in JS, but a lot of code). They are almost orthogonal languages. Will it fit your theory? :)
Are they both your favorite languages? Also there will always be exceptions.
Sorry for long reply. No, I prefer Rust, but right now it's impossible to use Rust on frontend. I also know there are people who love Python, Scala, Nim, D, Ocaml and I don't think they are wrong - it's just languages with different flavours and there are people with other preferences, so it's awesome to have alternatives. They are not better or worse than me if they use other languages, I'm more than sure about it. But when we talk about PHP, Go, Perl - yes, I think people could make better choice.
That's actually an interesting philosophical question. I find the idea of "more than one way" extremely unappealing, so it's not particularly shocking that Python is my "ideal" language. To me it's either useless (all options have the same efficiency) or it's bad (one option is the most efficient). So it seems senseless.

And artistic is the last word I'd use to describe myself.

I should probably have added "job" to that list. People certainly define themselves by their jobs. Not everyone all the time, but you can see it cropping up somewhere all the time even within a company.

And job grades, job titles, job seniority, place of education, type of degree, ...

Very sorry to make an aesthetic complaint, and Raleway is a fine font for certain applications, but blogs that use low contrast fine raleway for the body text just kinda make me want to read something else.
Very sorry to make an aesthetic complaint, and Raleway is a fine font for certain applications, but blogs that use low contrast fine raleway for the body text just kinda make me want to read something else.
Why would anyone think Go and Rust are bitter rivals? They're great tools for different things, with a broad margin of overlap.
Ultimately, they share a space - compiled, memory safe, and aimed at server-side development.

The way they differ is mostly in how they approach memory safety, which gives them different performance characteristics.

Go is about making every distraction from the thing you want to do go away. There's only one way to do it, built in and good enough. Batteries are included. Compiling is painless. Deploying is painless. Just add algorithm.

Rust (which I understand less) seems to be about making a program that does exactly and only what you said, including deterministic memory. The safety is less about a general intent to be safe, and more about guaranteeing invariants that are needed by deterministic memory deallocation. Its natural hunting ground is real time - any program that has to finish things by deadlines.

Rust isn't solely aimed at server space: E.g. we have servo, a browser engine.
"aimed at" and "used for" are never disjoint sets.
Couldn't this argument be made about all languages? People into dynamically typed languages would have statically typed languages for the same "don't touch my identity!" reason.

I personally don't "hate" go. To be honest, I have barely read 20 lines of go ever. But I do not like the idea of a language specifically designed to limit my possibilities. I want to keep seeing "programming" as an art and a creative activity. Not as a factory-like process where there is only one way to do thing, all developers are inter-changeable, etc.

I get why it's interesting for big corpos like Google. I just don't have to like it :)

Nature works in the same way that it limits us to the fact that an effect can only be obtained by its commensurate cause. Anything is possible through that law as long as the appropriate cause can be formed.
What??
In math, answers are made by questions. In life, the quality of your answers is determined by the quality of your questions. So make a concrete question based in reality if you want a specific, real answer that you can confirm against proof.
Wow, you did all that nature analogy to say that the misunderstanding lies in the question and not in the answers?
That's incorrect. I was talking about your useless "What??"
I think there is a better explanation for why people dislike Go. All programming languages currently used for the web have gigantic downsides. They're slow. They have terrible package management. They have poor standard libraries. They have no static typing. They have no visual debuggers. They have no good IDE support. They don't integrate well with frontend code. Some programming languages are more flawed than others, and no programming language fails on every front, but they're all pretty objectively terrible.

Then Google announces Go. A cross-platform systems programming languages for high quality web services. That sounds great! I can't wait to see what Google came up with.

So when people saw Go disappointment set in. It has some great properties, but the language is not expressive. So Go web frameworks (like Revel) generate Go code at compile time to get the dynamic parts working. Just like we did in the 70s to work around C's shortcomings. Want a container for a specific type? Code generation! It's so clumsy. The lack of exceptions makes writing correct code really tedious. A web service is not a device driver where every edge case has to be carefully considered. Bailing out with an exception is fine. Go disagrees.

I think the disappointment in what Go could have been explains the vocal dislike. There are only a few companies in the world that can create a new programming language and ensure it becomes popular. Don't get me wrong. Go isn't a bad language. It's just not the language that will push the web forward, and Google was in a unique position to create a programming language that would.

> A web service is not a device driver where every edge case has to be carefully considered. Bailing out with an exception is fine. Go disagrees.

If all you want is a bail out mechanism then panic.

"All" languages used for the web have those downsides?

This is part of why Go culture scares me a bit. You seem to be overlooking the huge amounts of software written in .NET and on the JVM, none of which suffers from the problems you just outlined: there are great IDEs, decent type systems, good interactive debuggers, strong standard libraries, reasonable package management etc.

This mental blind spot towards the tools and practices that a massive part of the software industry has been using for years is really odd.

I deliberately didn't mention specific programming languages because I knew that would lead to bickering about the relative merits of Python vs Java vs .NET vs Clojure, which would just distract from the greater point. Your curious assertion that I'm somehow part of "Go culture" only confirms this.

I think we can do a lot better than .NET or Java. .NET isn't even cross platform and Java has a lot of legacy cruft. Not to mention both platforms are pretty bloated and not even designed with the modern web in mind.

So much bias in this thread in general. Have you missed the news on .Net Core?
A sample from the newer stuff in the .NET world: http://nancyfx.org

How modern is that for you?

Same old same old? If you think nancyfx represents a leap forward I don't know what to say.
It's not clear what you would accept as a good language for the web. Could you elaborate?
Comparing to the old ASP.NET web sites with "view states" and "user controls"?

Sounds like leaving behind the "legacy cruft" you talk about to me.

"Decent" is being very kind to any language that has a type system where every reference type is implicitly a Maybe (okay, Scala exists).
Go and Scala also allow every pointer to be null, no? Scala has an option type, but so does Java 8. Defining one in C# is easy.

But there is Ceylon, Kotlin, Clojure, whatever. Kotlin uses ? suffixes to define if something is optional. And at least the code interops nicely. You can inherit a huge Java codebase and slowly convert the code over. No such luck with Go. Unless you're converting into C!

C# and Java optionals aren't very useful, since they would be reference types themselves, and thus could be null!

I would submit Rust and Swift as "decent" type systems, if Haskell is the standard for "good". They do nullability correctly, but lack HKTs.

In Scala, Option[Whatever] may also be null. The difference is that it's considered "some Java compatibility leftover" and never exploited by any sane piece of code.
Java and C# have a first class ideology (object oriented) that does not align well with functional web servers which is how almost everyone writes theirs nowadays.

These languages are getting better about it, but they are tacking on functional programming to a language that traditionally was strictly OO, and in the same way C++ has a lot of edge case behavior in being "OO tacked onto imperative" these languages suffer similarly.

Both of those languages have migrated to more functional features with closures and lambdas. In fact, it seems like the entire landscape has tilted a bit toward the functional side in the last ~5 years.
Last time I checked there was plenty of FP choice on JVM and .NET stacks.
That's not a true statement about modern C# and Java.
I can really relate to your post. I heard about go at a time when i was angry against python for having no type hinting and started to see people build tools parsing types in code comments, and at the same time being furious against the gigantic bloat that the java enterprise web frameworks had become.

So, as you said, when i looked at go being a smart and small with a modern standard lib, and being modern in a way with its approach to interface programming i thought i would fall in love with it.

Then i saw go didn't have a single generic function for comparing two numbers, because the language wasn't generic enough, and i felt hugely disappointed.

Why would you even want that? I mean, I've heard the generics argument before, and I'll accept that they are important for some applications (esp custom data structures). But lack of a generic `Cmp` is the straw that broke the camel's back?
If you avoid Spring, you can find some pretty nice and straightforward web frameworks in the Java space. The reason they often seem bloated is simply because they've been around a long time and so have accumulated many features.

If you want something similar to the Go standard library HTTP server, there is this one that comes with the JDK out of the box. Most people don't know it's there though, as technically it's not a part of the Java platform, it's just something that comes bundled with the standard JDK:

https://docs.oracle.com/javase/8/docs/jre/api/net/httpserver...

If you're building a serious app you will want support for more advanced stuff. That's when you can upgrade either to a better HTTP server like Jetty, or to a full web framework that bundles templating, authentication, database access, session management and all the rest. Play! Framework is quite well known. It ignores all the standard enterprise Java conventions in order to be a lot more opinionated. If you like their opinions, that sort of approach can be way lighter.

Elixir is fast, has good package management, has a good standard library, exceptions are easy to read and debug, etc. Elixir doesn't have static typing, but it is functional, so it doesn't really matter as long as your initial assignment is correct. I can't really comment on IDE integration, since I never use anything but Vim.

Maybe the static typing and IDE support are enough to make Go awesome for some, but they don't really matter to me as much as concurrency, hot-plug code deployments, the actor model, and stability.

(comment deleted)
(comment deleted)
(comment deleted)
> Then Google announces Go. A cross-platform systems programming languages for high quality web services.

Did they actually advertise it as a language for web services? I thought it was designed for command line tools mostly, not for serving HTTP/HTML.

I came here to say this. It's not fair to criticize Go as not optimal for web services if it wasn't designed to be optimal for web services.
"The lack of exceptions makes writing correct code really tedious."

Tedious up front often translates into time saved down the road. Exceptions are often an easy way out while accruing future debt.

Unfortunately, our industry cannot easily measure the time saved down the road and so cannot properly value it. However, many with long term interests in a project will often spend on the "tedious" costs up front to avoid potential future costs.

> Exceptions are often an easy way out while accruing future debt.

Is there perhaps a concrete illustration on how using exceptions causes technical debt, especially in a GCed language like Go?

The advantage with go is that errors have to be handled right away by the thing that may have caused it. The is versus, say a try/except with a dozen lines of code in the try, and then something like `except KeyError: pass`. You may have no idea which line caused the error or why it did so.
The general principles for fault tolerance require Separation of Concerns vis. Error Encapsulation (make sure that the contagion doesn't spread), Fault Detection (make sure that you know that someone is infected), and Fault Identification (you have ebola!).

Error encapsulation (and this applies equally to modules, components, systems, architectures, organizations) is invariably best done at the lowest level possible, which invariably breaks #3 and #4 (fault detection and identification).

what if you have different classes of exception handling mechanisms available for each of these cases? What about languages that may support exceptions, option types, tagged values, multiple return values, signals, continuations and/or whatever mix of them that exists?

The problem with handling everything right away is that it lacks flexibility to handle things in what could be the optimal manner. "One true form of exception handling", to me, sounds as reductionist of an approach as "one true form of concurrency", "one true programming language paradigm", or whatever.

Treating all error conditions / exceptions with the same mechanism will generally ensure that you pick similar stances on encapsulation vs. detection and identification for all error conditions / exceptions, unless you decide to be extra careful about all of that.

Using multiple mechanisms will allow you to pick, case by case, which one you feel is worth breaking depending on the nature of the fault and what your specific application or system requires.

I feel Go is doing a pretty bad job at this.

"The problem with handling everything right away is that it lacks flexibility to handle things in what could be the optimal manner."

You can pass the error (or another) up the stack. The language is flexible.

"Passing up the stack" is fairly minimalistic in an environment where you could be running thousands of goroutines, some (many?) of which may share memory.

If you do it that way, you seem to forego a lot of error encapsulation straight away and quickly find yourself into undefined territory.

doesn't matter whether no goroutines or thousands - you either handle errors or pass upwards. Anyhoo, just pointing out that it has the flexibility to do either.
mononcqc is pointing out that those aren't the only options: other error-handling mechanisms exist. The options are not either "handle the error right now" or "make the caller handle the error".

In fact, in go those aren't even the only options, since you can pass an error object up the stack using panic/recover.

An alternative model could have error handlers registered somewhere and be invoked at the point the error occurs, either choosing to pass control to another part of the program, or resolve the issue and continue processing. That could, of course, be implemented in vanilla Go, but then everything has to agree to do that.

Some systems are able to distinguish the point where you recover from an error from the point where you report an error: e.g. a batch processing system may recover from an error by skipping an item to be processed (and perhaps storing it in a list of failed items to be inspected later) and another "catch" handler further up may decide whether and how to display a diagnostic about the issue. Of course, this logic could be embodied as a "reporting" object which is passed down to the batch processing algorithm, but hooking into the exception handling logic means that you can use the existing error-reporting infrastructure.

Common Lisp has a system of "restarts" where one can configure multiple ways for a handler to respond to errors other than simply passing it up or carrying on. For example, a batch processing system might set up restarts to allow items to be skipped, retried now, or retried after the batch finishes. The batch processor itself might have restarts for retrying the batch or rescheduling it on another node. Above the batch processing algorithm, an exception handler can look at the situation from a high level and decide what to do: e.g. it may determine that the batch has grown too big for the node and reschedule it on another one.

Until the decision is made, the stack is not unwound, so if I decide to restart an item from the batch, I just jump right back into the still-running batch processing function. This design allows the mechanism for how to actually deal with an error condition to be separated from the decision as to which mechanism to use. It's very much like breaking into a debugger, except the program can debug itself.

In Erlang, a program handles errors by keeling over, dead. Because an Erlang system is (meant to be) designed as a swarm of cooperating processes, an individual process can just die when something goes badly wrong and its compadres are expected to have registered an interest in knowing that this has happened. A common design pattern is to have a dedicated monitoring handling process which knows how to orchestrate things so that one broken process doesn't cause a cascading failure through the whole system.

In the running example, a batch processing system might spawn a process for each batch, and a monitor process might check for batches which die and then decide whether and where to restart them.

That said, Erlang still has a fairly traditional try/catch system for when that makes more sense. And errors are objects, so you can return them up the call stack as well.

There are many more mechanisms for error handling which aren't simply "handle here or pass up".

> You can pass the error (or another) up the stack.

(C++-like) exceptions pass the error up the stack. Directly to the right place, and ensuring that clean-up takes place along the way without tons of repeated test-and-bail code.

Lisp-like are one better: the stack is searched for a binding to a function which handles the error, and then a new call is generated to that function. If the function returns, the search for the next possible one continues. Or the function can then look for a restart point somewhere the stack (the entire stack still being intact), and perform a dynamic non-local transfer (a big return) to that point.

Dumb error return values make it very easy for an error to disappear without being handled. Oh, the caller has a few things to do before returning your value (things such as clean up that could be an unwind block!) and fumbles the ball somehow, and ends up returning a different value: the information is altered like in the telephone game.

That's the problem: every function level between the source of the situation and the place where it is to be handled intercepts the handling effort by being involved in the control flow. When it should just be getting the heck out of the way (like cars pulling to the side when they hear an ambulance).

Bubbling up error values is an excellent example of an "Anti Pattern".

Not handling an error from something you called into will lead you to be bypassed when it jumps "directly to the right place".
Actually the real idiom is not "handle errors where they happen" but rather "errors are values" (https://go-proverbs.github.io/). This means that there is no one true way to handle errors, but rather that it's up to you to build error management with the same tools you have to manage data. Maybe you want to process a list of stuff in parallel and report the first error that ever happens, the same way you'd want to use the first useful data that was processed by one of those parallel processes. Maybe you want to multiplex the error to multiple error processors, for some reason. Maybe you want to signal a watchdog but continue working. I believe bubbling up the error is a consequence of the Go community still being young and not having invested a lot in proper error management (especially since you don't always need something fancy) more than it is an idiomatic way of working.
That's the thing though. Errors can be data in plenty of other languages. It's just that it's not the only tool you're given, and there's other things you can do without having to reimplement it all from scratch every time.

Where a lot of people will say "go is opinionated", I keep feeling that Go is just not providing facilities I feel are part of what you should get out of the box (much like a standard library is one) and just shifts the burden to me to reimplement them all correctly. In doing so, you also lose the opportunity to have a well-designed approach that gets rather uniform adoption through the community.

I know the feeling. Having moved to Go from the Python community I felt extremely scorned by the lack of a lot of features. Why should I have to write a for loop to traverse this list just to see if an element is present? What I've found is that the features that are missing are actually extremely simple to implement myself - to the point where it's comical that I ever complained about them. The things you gain, however, are much more powerful. There is an elegance to go code that can't be matched by dynamic languages. It has the readability of Python with the type safety of Java, and tooling built in that simply trumps both. I'm obviously a big fan, but it was a long and difficult journey to get there.
(comment deleted)
Conversely, the disadvantage with go is that errors have to be handled right away by the thing that may have caused it.

Sure, with a `try`, you may have no idea which line caused the error or why it did so, but that isn't what matters. After all, if a function returns an error, you don't know what line of code actually caused the error. (Especially in go, since errors lack backtraces.)

With "exceptions" you know that something within the block failed and passed the information about what went wrong to the catch/except/rescue block. Problems arise if the block fails to tie up its own lose ends, but that's a problem that exists without structured exceptions: if a function might return an error you still have to take it on faith that it arranged for clean-up of any state that, outside the function, would be problematic.

Fundamentally,

    try {
          foo()
          bar()
    } catch e Fred {
          cleanup1()
    } catch e Barney {
          cleanup2()
    }
isn't really any different from

    if e := (func()error{
        if e := foo(); e != nil {
            return e
        }
        if e := bar(); e != nil {
            return e
        }
        return nil
    })(); e != nil {
        if _, ok := e.(Fred); ok {
            cleanup1()
        } else if _, ok := e.(Barney); ok {
            cleanup2()
        } else {
            return e // assuming this function returns error
        }
    }
except that one of them is far more readable.

It's potentially different, of course, inside foo(), where it might unexpectedly call a function which raises. But because recover exists in the language, robust functions must assume that any function call, or various built-in operations[1], might result in code further up the call stack recovering from a panic, so it must make sure it will fix its inconsistent state when the stack is unwound.

Additionally, go is inconsistent in that some errors - e.g. array index out-of-bounds - cause panics instead of indicating errors normally. That's understandable, since having to type

    if c, ok := array[i]; ok {
      err = fmt.Errorf("Array index out of bounds")
      return
    } else {
      // do something with c
    }
every time you wanted to do

    c := array[i]
would be really tiresome.

[1] Such as: comparing non-comparable objects via references of interface type; dereferencing a null pointer or interface; out-of-bounds array/slice/string indexing; division by zero; sending on a closed channel. All likely occurrences.

GC means that most memory leaks cause by poor exception handling code are auto-magically fixed but it doesn't fix other resource leak problems; file handles, memory maps, locks, etc.
Nope. Because like most popular language constructs they can be used effectively or poorly. There are a ton of completely valid arguments on both sides.
Lack of non-local dynamic control transfers with unwinding is the real deal breaker.

Exceptions are a red herring; they are just something you can build if you have dynamic control transfers with unwinding. And if you have macros, or at least some kind of access to the language to bend the syntax. Plus perhaps other goodies like testing whether some object X is of a type which is a subtype of T so you can make exception handling frames decide whether the elevator stops here.

The underlying control mechanism not being there makes the language crippled.

Just give me C. Then I also have forty years of research out the window: but but at least with setjmp and longjmp.

How does Bash recover to the top level prompt when the scriptage fails deeply nested in some function calls? Why, longjmp! I will fake the unwinding if I have to.

Go has panic()/recover(), which is better than setjmp/longjmp (thanks to GC you won't leak memory like you would in C with setjmp/longjmp).

I'm not saying using panic()/recover() is a good idea but if your issue with Go is lack of non-local dynamic control transfer then good news: you're mis-informed and Go will be great for you!

It's not just up front. You only have to write the tedious and repetitive code once, but you have to keep reading it forever, because the code you care about is scattered here and there in the middle of it.
A web service has to consider errors more carefully than you might think.
> The lack of exceptions makes writing correct code really tedious

Go does have exceptions.

> A web service is not a device driver where every edge case has to be carefully considered.

Yikes, that's an assumption that is going to bite you hard in your career. I recommend escaping it as soon as possible. ;) The web is full of horror stories from people who assumed their part of a web-accessible product wasn't on a critical security / safety / reliability path.

I used to use Python and Ruby on Rails for web services; this is precisely why I left them. I got tired of dealing with typos becoming runtime exceptions.

> Bailing out with an exception is fine. Go disagrees.

Go makes it trivial to bail out with an exception: You panic. But panic is reserved for real exceptions, not common and expectable situations (like "file not found") and its defaults are therefore set to crash the whole process (which is fine if you're doing microservices and therefore can handle failures by crashing and restarting). I find other languages treat exceptions as not sufficiently exceptional.

> I used to use Python and Ruby on Rails for web services; this is precisely why I left them. I got tired of dealing with typos becoming runtime exceptions.

That is why you must do 100% code coverage on all non-compiled language.

I like Go but I hate my self for it.
Hating oneself is the highest form of love. -- Bill Maher on gay Republican politicians.
> Go is the only recent language that takes the aforementioned 40 years of programming language research and tosses it out the window [ ... ] no pattern matching, there’s no borrowing, there’s no pure functional programming, there’s no immutable variables, there’s no option types, there’s no exceptions, there’s no classes, there’s no generics.

Some of this stuff is quite a bit older than 40 years. That only brings us back to 1976. Exceptions are around mid 1960's or so (PL/I, Lisp). Functional programming, Lisp again, 1958. (Java-like) OOP Classes? At least as far back as Simula-67. Simula-67 is where C++ gets "virtual" from.

It's so easy to dismiss legitimate criticism of any issue as "hate" and "people are emotional" and "their identity is threatened".

At the end of the day, there is legitimate criticism of Go, just as there are legitimate advantages of using Go. As an additional fact, Go's core developers (and some users) have repetedly been dismissive of this criticism.

Yes, this article tries to make it sound like issues with Go are solely due to identity, but that's not the case.

If I like to use soap and analgesics, is that part of my identity or just common sense application of technology?

There are studies that suggest using analgesics may negatively affect your judgement, so there's that.
(comment deleted)
I never understood religious wars about programming languages and tools in general, and probably never will.

People built something with it that works/makes someone money/enables a given service? Then, as far as I am concerned, that given tool has proven itself good enough. Everything else is a circle jerk carried forward mostly by a bunch of masturbating monkeys who are better at talking instead of doing.

This is true for most any discipline, of course. Photography is another prime example. Arguing on forums instead of going out and producing pictures.

I'm getting kind of sick.

There are many good things in go, but some very weird stuff too.

Good things are multiple return values, lack of semicolon, optional braces for if and for, insanely fast compile time.

Bad things are forced curly brace style, complicated function declaration syntax, variable declaration which is too different from C in my opinion (type after the variable name).

I'd honestly prefer a language which is even closer to C or C++ in its syntax, with native maps, sets, queues, tuples, etc (pythonic stuff) without necessarily having templates or inheritance. I put a lot of value in syntactic sugar over overblown abstract stuff. Using plain struct with data oriented programming will be more than enough in most of the cases.

We are still waiting for C++ modules, which obviously might be lagging because C++ has an ISO standard and a lot of existing code which involves backward compatibility, but I think we need a new language that could be faster to compile, just like go is.

Types after variable names are here to stay though: they are in no way something new, and make a hundred times more sense when there is type inference: If writing down the type is optional, then it should go last.

Given that some level of type inference seems to be the future of strongly typed languages, I expect variable ahead of type to become more and more popular among language designers.

It is a bit more nuanced. Go's dislike is a function of how vigorous the hype for it was vs. how much it actually delivers + a few other things. In general I see it as this function:

  def dislike(hype, results, community, usage): ...
Note the usage, if technology is not used, it won't be disliked. So dislike is a good sign sometimes. Community attitude matters, how are creators and developers treating others, how are well are docs presented, but also how mature and behaved are the advocates of the technology. That is something creators can't necessarily control.

Other hyped technology is/was node.js. I've heard people say crazy things about, it is the best technology, everyone should drop everything and join the winning team etc etc, async programming is the future and if you are still using threads you are stuck in the past and so on. So it was hyped quite a bit. And then it would have been ok, if it actually delivered, if packages weren't broken and half-assed, if servers under load actually didn't crash and so on. If people who used it where a bit more mature, if there wasn't drama at every step and so on. So it ended up disliked quite a bit.

PostgreSQL is hyped, people are saying this is the end and all database and so on. But it is not disliked, and the reason is it actually delivers results. It handles JSON blobs, it does other things right, it doesn't catch on fire, doesn't throw your data to /dev/null. So it not disliked.

As for Go, I haven't used Go, so I don't have much of a comment, but noticed an interesting nuance with how some technologies just happen to be disliked while others, even if hyped are ok.

I did not like go until I tried it out on small pet project. Now I know how to enjoy it.
Same. I hated the idea of it before I started to use it and started to use some of the tooling (like goimports, gocode, etc) with the go-plus package on Atom.

I think tooling really makes the difference in this case.

While I agree with the premise of the article, I don't think this is why I don't use Go. I don't hate Go, but I also don't think it brings anything new or elegant to the party. Languages like Rust and Elixir are exciting to me. Go just feels like a rerun of everything I've done before.
I've been using Go for several months and love it.

"People shouldn't like things I dislike." --waaaah

I would burn Go with fire and salt the earth because it's the bloody compiler will refuse to compile my valid code if I have unused imports or variables. It makes programming in Go a terrible experience and that's why I won't touch it.
You'll love goimports then.

https://godoc.org/golang.org/x/tools/cmd/goimports

Hook it to your editor's save command and never worry about imports again.

On the other hand, stop leaving unused variables around...

I hate debugging someone else's code that has unused variables in it as much as this guy seems to hate the go compiler.
Any normal compiler usually allows overriding these options. I normally write Haskell and it has it all: unused variables, unused imports, name shadowing, non-exhaustive pattern matching, everything. But these things are warnings in my dev build and errors in the release build. That's a sane way to do it.
Except some people wouldn't enable -Werror, and the quality of Go code would suffer on average.

Plus, now your compiler has options.

Yeah. I'm a fan of mandates when it comes to things like compiler options. Everyone should just suck it up and work with the same constraints. Warnings are just errors without balls.
> On the other hand, stop leaving unused variables around...

I don't think there's any problem with doing that. I use a linter to stop me committing code that has unused variables in it, and to highlight those kinds of style issues in my editor so I'm aware of them. But for a compiler to refuse to run unpolished code in development is just bad design.

It's as if Go's designers took the hubristic or naive view that all code would, in an ideal world, be typed out perfectly first time, as opposed to being gradually hammered into shape through trial and error. This is worse than a design flaw, it feels like an active imposition.

I think that behavior is annoying, too. I've wonder if there's a way to tell the compiler to generate a warning for unused variables instead of just erroring out.
No there isn't. Because Go loves to show you the middle finger.
Thank you for your constructive comment and downvote
This to me is one of it's benefits - uncommented, unused variables shouldn't be in code, and I like that the compiler is actively preventing me from being lazy and creating cruft that's simple to remove.
Article didn't convince me to think following arguments are wrong:

* Go is a language stuck in the 70’s.

* Go ignores 40 years of programming language research.

I tried to use Go and was shocked how they can use it without package manager, without generics, with so brittle concept of channels, with executable comments in code and with so authoritative model of taking decisions about language evolution.

So I still think criticism of Go is valid and authors are still deaf to it.

I feel like the designers of Go tried to address criticism of C without considering any language designed after C. As a result there are improvements to some of the most egregious shortcomings of C (undefined behavior, a lack of basic reusable building-block data structures like lists and maps, crude build systems), but the subtler issues with C are still there. You still need to delicately route together error signals from every procedure which could fail. You still have a very limited ability to create new, reusable data structures. Common patterns are copied and pasted around your codebase because you have limited tools for abstraction and reuse.

Go proponents claim it's simple. I'm more inclined to call it simplistic.