Hacker News new | past | comments | ask | show | jobs | submit login

I have said it before and I will say it again - for all the deficiencies Go has, it is somehow highly compatible with the way my brain works.

One point the article does not mention is the documentation. I think Go's documentation is excellent, it does not overwhelm the reader with its volume, but mostly anything one might want to know about the syntax and semantic can be answered by carefully reading through the documentation that comes along with the development tools.

Also, there are some pretty neat static analysis tools for Go out there, and since they are mostly developed in a development-environment-agnostic way, they tend to be usable from a relatively wide range of editors and IDEs. But even just using go vet and golint regularly goes a long way to rooting out all those tiny but tedious bugs and ensure a degree of consistency in naming conventions.

I still do not see why somebody in their right mind would willingly prefer camelCase over using_underscores, but the fact that my code is laid out in the same way as that of third-party libraries means it is surprisingly easy to dive into somebody else's code and make sense of it. The fact the Go community tends to favor simplicity over brevity can get annoying at times, but when you have to read somebody else's code to figure out if it's buggy or you're using it wrong, it is priceless.

There a many things Go could do better (or at all), but if there is no way to implement some feature without sacrificing simplicity, I prefer simplicity. I you want C++, as the saying goes, we know where to find it. ;-)

(I'll admit though that the C# designers have done an impressive job at adding lots of features without the language collapsing under its own weight. So it's not like it's impossible.)




I still do not see why somebody in their right mind would willingly prefer camelCase over using_underscore

My taste is the opposite: I can't understand underscores in identifiers, it's like having hiccups inside every thought.

But what saddens me is that we're still having this conversation in 2017. It would be trivial for editors to support either style, if only language designs included the concept of word separator inside identifiers, which could then be rendered at display/edit-time according to user preference.

Somehow programming languages are extremely resistant to these kinds of improvements. ColorFORTH is the only example that comes to mind of a language designed beyond ASCII.


> But what saddens me is that we're still having this conversation in 2017

It is a pointless but easy thing to debate about. I find Go's solution of de facto forcing a certain style on everyone a little harsh, but it is effective.

> It would be trivial for editors to support either style

Emacs has glasses-mode which displays underscores in camelCase identifiers without changing the source code. It's not the most elegant solution, and when I first heard about it and gave it a try I was working on a code base that used both camelCase and under_score, so glasses-mode actually made the code more confusing, because I never could be sure if the underscore I saw was actually there. But on a code base that uses camelCase consistently, it might help.

My point, though, was that it does not really matter that much - if you come from an underscore_heavy_background, it takes some getting used to, but that is all. Once one is used to it, the consistency across not just my own code but the entire ecosystem really pays off.

> the concept of word separator inside identifiers

That sounds like a very interesting idea. But I think it is probably nearly impossible to introduce into an existing language without breaking a lot of stuff. Perl[56] maybe, there is a package to program Perl in Latin, and if that degree of craziness is supported, I am sure it's possible - it just won't be pretty.

Lua comes to mind as well, because in Lua an identifier is just a string used as a key for hash table that holds the local environment. This is exposed to Lua scripts, with enough cleverness one might add something there, too.

And there's probably a couple more that I missed. ;-? Has anyone actually done any experiments/research in this area?


Nim allows either style in the language directly: https://nim-lang.org/docs/manual.html#lexical-analysis-ident...


My background - self-taught in C, wrote BASIC to make money in High School, learned Java (and used professionally). Eventually ended up with Ruby (Rails). I developed my own LISP-like for many years.

Now most of my hobby programming is in Go. I really like it's connection to C. You feel the connection through to lower level programming. I also like the emphasis Go both emphasizes data structures and is first-class with functions. The combination of the two are really easy for me to navigate, but extremely expressive too.

It feels like a language that is very grounded in the fundamentals as I see them, but with a modern outlook and tooling. It feels amazing to write a web-based application with the power of C, but feeling confident you're not going to blow your own foot off every step of the way.


> I still do not see why somebody in their right mind would willingly prefer camelCase over using_underscores

A lot comes down to preference and which language you're used to program, but here is an objective fact: having to reach for the underscore key with your pinky finger on shift is a hassle, especially when you have to do it so often.

I suspect it accelerates exposure to carpal tunnel syndrome too.

In contrast, the uppercase letters required for camel case can be done either with two hands or with one hand but without reaching as far as you need to to reach the underscore key.


Go is an alternative for C (for services), PHP, and server-side JS. I don't understand why people keep comparing it to languages like C++, C#, D, Java, Rust, or Scala. The problems these two sets of languages solve are fundamentally different.


>The problems these two sets of languages solve are fundamentally different.

I'm afraid I fail this intelligence test. What problems are solved by C, Go, PHP and server-side JS but not by any of Java, C++, C#, D, Rust or Scala (and vice versa)?

This seems like a completely arbitrary classification to me.


Sorry, I had thought that it was quite obvious: JS, PHP, and Go are almost exclusively used for web-related tasks. Yes, one can find other usage examples, but by and large, that's their main field of application.

To expand on this, imagine building some complex application framework with these web-oriented languages. Without decent abstractions and insufficient typed programming support (see e.g. TypeScript to JS transpiling, or writing your own preprocessor macros to simulate generics in Go to avoid having interface{} everywhere, etc), and certainly no support for annotations, macros and other meta-programming techniques. Yes, not all of that high-level stuff is great and takes time to master, and so I understand the niche of Go & PHP & ss-JS: You need to quickly scale up your web services startup, which is often poorly paid work, and so you can't afford experienced developers. Having a simple, common, easy web services development language where you can hire any freshman and get them productive is great. So I'm not saying Go is bad or useless, but it only fits a (big - even, possibly the biggest in software engineering) specific case. ASP, PHP and Node.JS et al. are horrible compared to Go at that, but were the options you had before Go came along, so it's a godsend for web developers.

I hope that explains why I don't see Go as comparable to complex, high-level languages - and in no way in competition with them, in fact.


> JS, PHP, and Go are almost exclusively used for web-related tasks

JS is used for GUI tasks too, so your point seems totally arbitrary. Java is heavily used to write servers and services as well.

> I hope that explains why I don't see Go as comparable to complex, high-level languages - and in no way in competition with them, in fact.

Javascript and PHP are complex high-level languages as well. Your point doesn't make any sense. Go is the way it is because it was designed that people who rejected 30 years of type theory. But now they have a problem, because they repeated the same mistakes as C and now they are planing to break everything with Go2? they just quietly admitted they were wrong, it's time to admit you are wrong as well.


PHP does indeed have features that make it more suitable for writing server side page templates, and JavaScript has a unique position in client side web development.

But I see very little in terms of features or problems they solve that distinguishes Java, JavaScript, Go, Scala and C# from each other when it comes to writing Web backends. It's essentially a cultural choice. So comparing them (and many others) is totally fair game in my opinion.


> I see very little in terms of features or problems they solve that distinguishes Java, JavaScript, Go, Scala and C# from each other when it comes to writing Web backends.

So in a way, we agree, as that was my whole point - Go & it's predecessors (ASP, PHP, JS, ...) are mostly only good for Web backends: E.g., literally all Go developers I know personally are either fresh out of college or ex PHP programmers, ASPers and JS hackers, and all work exclusively on web development stuff. (But my sample size is maybe a dozen companies, so that's possibly biased, I agree.)


What I disagree with first and foremost is your claim that Go is not an alternative for JVM/.NET languages and hence shouldn't be compared to them.

All of these languages are direct competitors in a number of areas today (Web backends, infrastructure services, database systems) and based on language/runtime capabilities (as opposed to cultural and library availability) I see almost no area where there is no potential overlap in the future.

Also, what a language is currently used for and what it is good for are two completely different things. There was a time when Java was mostly used for Applets and desktop user interfaces. It wasn't good at either.


For the sake of argument, let's assume Go were equal to Java and C# (nb, I think that is not true, but let's look at the issue from that perspective).

Can Go replace C#? That's MS land and comes with the .Net platform. I think nobody will think Go is even remotely gathering its following from C# and the amount of tooling you get there is probably the largest set you can get.

What about Java? That has 20 years of entrenched Enterprise usage. So to make a dent on that, it not only has to have equal languages facilities, it also needs an equivalent ecosystem (maybe?) and, crucially, has to be better: Java replaced C++ as it's a much better fit at what it's used for due to GC and "no" resource management. But I certainly don't see anything that Go does that makes it much better over Java as Java was in it's day over C++.

So no, I don't see Go replacing .Net or the JVM anytime soon.


That is a long list of straw man arguments. You keep refuting claims I never made while ignoring my point.

I never claimed that Go is seeing any significant uptake in Java's or C#'s historical strongholds. I'm not talking about current usage at all. I also didn't say that Go is going to replace .NET or the JVM. I didn't even say that Go is better at anything.

None of what you keep going on about has even the slightest thing to do with the point I was making.

My point is very simple: Go, Java, Scala, C# and their most widely used implementations have similar enough technical capabilities to be useful for many of the same tasks. Therefore it is useful to compare them.


As I said right off the bat, if that's your argument, where are things like: generics, error handling facilities, macros, reflections, annotations, etc. in Go that are provided by Java, Scala, C++, C#, and Clojure?


What you need for a useful comparison is two things that are substitutable for each other in a particular context but not identical.

Go vs Java meets these criteria. That's all I'm saying.


Which is why I said, we (mostly) agree: Go is great for web backend development, as I've never disputed in any reply, quite the contrary. My point was and is, that's all there is to "compare" - even if that area might be the biggest domain in IT right now.


Here's what you said:

>Go is an alternative for C (for services), PHP, and server-side JS. I don't understand why people keep comparing it to languages like C++, C#, D, Java, Rust, or Scala.

Your claim was that there is no overlapping area of application and hence comparing the languages makes no sense. That is where we disagree if that is still your opinion.

Besides, I see abolutely no reason why Go couldn't be used for writing something like Cassandra, Kafka, Spark, Hadoop or a core banking system. None of these are specifically Web backends. Equally, I see very little reason why Docker or Kubernetes could not be written in Java or C#.


I think our semantical differences are mostly due that there I was referring to language level facilities, then, while even in that post I clearly underlined Go's utility for web development.

As to transactional processing, there's a reason why that's not using GC languages and why the banking and oil industry are one of the few mainframe clients left. Just because you can do X with Y, it doesn't mean it's economically or technically feasible.


Don't underestimate how much our industry is driven by fashion, culture, corporate backing, historical coincidence and inertia. Very few decisions are based on technical merit. Go read some of those "why we switched from X to Y". It's 99% rubbish ex-post rationalization of nothingness.

In my opinion there is only one significant technical dividing line between language implementations: Mandatory automatic garbage collection.

No other purely technical characteristic makes a whole lot of difference for the sort of problems that can be solved with comparable results using different language implementations.

That's why it doesn't make much sense to me to put Go in a different basket than Java or C#. Doesn't mean there is no reason to prefer one over the other of course.


If your baskets are GC vs. managed languages, I fully agree. But I don't think that comparing some contents in either of those baskets among each other necessarily is a task worth tackling...


So if I'm starting a new project and I know that I can achieve the same result with either Go or Scala, how do I choose without comparing?


What I meant is that the lack of features in Go has made it easy for us: All existing comparisons are probably sufficient.

All you need to decide on now is if you prefer syntactic simplicity over percieved feature boat, if it's a web development project or not, and if you can benefit from existing code in your language of choice or not.

Pick at least 2/3 to decide... :-)


I continue to fail to see your argument: First you claim that any language can be shoehorned into any usage, and then (last paragraph) you yourself show why that isn't quite true.

Plus, as said, Go's language "facilities" are a long shot from Java/Scala/C#'s, while having GC can be prohibitive in other areas (C++, Rust, embedded systems, real-time transaction processing), and some areas (e.g. space exploration) even need the ability to change the runtime code on the fly.


>First you claim that any language can be shoehorned into any usage

I did not claim that at all.

What I dispute is that the set of tasks for which both Go and Java/.NET are suitable is so small that it makes no sense to compare them.

People often have a choice of using Go, Java, Scala, C#, etc, for the same task and that is why a comparison makes perfect sense.


As I've explained here extensively, I don't think that Go is replacing any of the more fancy languages like Scala, Clojure, D, ... And as for C++, that's in a different domain. Finally, Java & C# are entrenched and Go has no decisively better advantage that would make it worth giving up those code bases (like Java was over C++' resource management).

I do agree that Go has made the life of legions of PHP and Node.JS developers easier. And it is nicer to do web development in Go rather than C and Python.

However, claiming that Go "eats everybody's lunch" is rather outlandish.


>However, claiming that Go "eats everybody's lunch" is rather outlandish.

I didn't say it was. I said comparing Go to Java or C# is useful because these languages are suitable for many of the same tasks.

What you are making of this pretty uncontroversial statement is mind boggling.


Just as in the other thread, the only unfounded claim is that Go provides similar facilities as Java or C# at language level. Go was explicitly designed to avoid all that, after all. So comparing those three at language level only surfaces a long list of things you can do in Java, and an even longer one for C#, but not in Go.


That makes absolutely no sense. Languages with very different features can be used for solving very similar problems and hence a comparison can be useful.


The keyword here being "different". I don't think that the utter absence of features is terribly interesting. To me, that's just a matter of taste.


Here is an even better way of putting this; I believe Go hasn't been used for any of these areas: game engines; scientific simulations; military usages; planning, logistics and operations; space exploration; embedded systems and industrial software; robotics; etc. etc. etc. Go is great for one thing, mainly: highly concurrent problems with large 99th percentile latency permissions, which mostly means web development - and that is "coincidentally" something Google is interested in, too.


You keep mixing up what languages are currently used for and what they are suitable for.

There are very few projects for which you couldn't use Go, JVM and .NET languages equally well purely on the basis of language and runtime features (ignoring hiring, library availability and other cultural aspects)


The entire category of "you need non-standard datastructures" works perfectly well on the JVM and .NET CLR, but is entirely useless in Go (thanks to missing generics).


Of course you can write non-standard data structures in Go. The fact that Go makes this more inconvenient or less efficient than languages that have generics is exactly why we compare the languages, not a reason for not comparing them as fnl has suggested.


It is always possible to compare any two things. The real question is if there's something interesting to learn.

We learned that the goroutines & channels concept isn't that bad an idea, but that it doesn't prevent you from stumbling over weird race conditions in large, distributed systems. Beyond that, at best one might argue if the lack of nearly all advanced programming features in Go is in itself a feature or a shortcoming.

However, I think that depends more on your personal preference on programming styles, so there's not much more to be learned from arguing about that. So that is why I see there's little that can be learned from any such comparison beyond what's well known already.


I can say for myself that I am learning a lot from comparisons and even from language flame wars. They give me an incentive to think more deeply about the implications of particular features and architectures and avoid stumbling blindly into well known pitfalls.


That, finally, is something I can underwrite 100%, too! :-)


"for all the deficiencies Go has, it is somehow highly compatible with the way my brain works."

I have been tempted to write a blog post about "Why People Actually Can Write Real Programs In Go." To listen to HN complain about the language you'd think that it must be clearly impossible to ever write a program of any kind without massively copying and pasting everywhere, when in reality I find it's actually quite pleasant for a non-trivial subset of programs.

The short answer is that it has a lot of features that people, generally not being used to them, work better than people may realize from the bullet points and often work together better than people realize. Favoring composition over inheritance is a legitimately good choice. Being able to declare interfaces that other objects I don't control conform to has a lot of little effects that you wouldn't anticipate in advance, to the point that while I understand the bondage&discipline impulse to require code to declare what interfaces it supports, I would consider that a legitimate mistake in most of the languages that do that. (In practice, it turns out the problem of "accidental satisfaction" basically doesn't exist. We learned that from the duck typing languages like Python and how they never really had a problem with that.) And while the grand concurrency stuff may seem neat, the little stuff can be nice too; just yesterday I wrote some code that takes a list of servers to query for some particular thing, and it was easy to write it to do them all simultaneously; that wasn't a Grand Architecture thing, it was just a function that casually did something that is a royal pain in many languages. (There are also languages that can do it better; I actually know many of them. Erlang would be roughly a tie here and Haskell could look really awesome if you put a bit of work into it. Elixir might beat Go, not sure, but I know Erlang itself doesn't.) And there's some other things like that.

The other thing about Go is that I like it for work, but not necessarily for my hobby. The thing about all those restrictions in Go that apply to me is that they symmetrically apply to my coworkers. As much fun as a more powerful language can be, it becomes a lot less fun when you've got dozens of developers trying to work in one code base in those languages; what is power for you is power for them, too, and, well, let's just say they are not always going to be the most expert developers in the world. I've seen... things. And at times, I've even been the one who did the "... things". So even though I know how to use Haskell productively and generally correctly, I'm generally very uninterested in introducing it into the team environment that I have. This is, IMHO, a very important point that I don't hear discussed often enough.

Basically, if you take HN's opinion of "Go is useless and should be wiped from the face of the Earth" as a scientific theory that predicts how useful it would be, the theory is falsified. It is useful and some of us even enjoy it for certain tasks. But I for one would never suggest it is useful for everything and actually frequently warn people off from certain tasks.


Many of us, old timers, surely programmed in languages like Go in the past, and were able to deliver lots of successful projects into production.

I for one was a very passionate Oberon user and Niklaus Wirth is well known for its minimalism design goals, Oberon-07 is even more minimalist than Go.

Just because I used to program like that almost 20 years ago, doesn't mean I still enjoy using such minimalist languages.


I absolutely agree that there have been a number of similar languages in the past, in various variations. However, the only one I know of that may have a claim to have gotten to Go's size or perhaps even larger (relative to the time) is Delphi. Go is, if not the first, the first in a long time to be something that can be practically commercially used. (I mean, you can use whatever language you want commercially, but there's definitely more barriers to some than others.)

Also, I can't help but point out that I didn't say I enjoy it for all uses either. I don't do my hobby programming in Go, because I don't have the issue of other programmers doing things I disagree with or don't like. Even if I do something stupid in another language, at least it's my stupid thing and so I tend to understand it better than somebody else trying to come in and see it.


> I have been tempted to write a blog post about "Why People Actually Can Write Real Programs In Go." To listen to HN complain about the language you'd think that it must be clearly impossible to ever write a program of any kind without massively copying and pasting everywhere, when in reality I find it's actually quite pleasant for a non-trivial subset of programs.

People like you are missing the point.

Yes, you can write anything in Go and with "interface {}" everywhere in your codebase. Like you can write anything in Javascript and not care about type safety since it's weakly typed.

However, not caring about compile time type safety with a compiled language is intellectually lazy. I'm talking about both go designers and developers here.

People want generics not for the sake of it, they want it because they want to write compile time type safe code, that's what generics are, just types.

"interface {}" everywhere isn't "caring about compile time type safety". It's using Go like it is python. What's the point of a compiler if the programmer has to do its job? that the issue with Go. Too much stupid run time tricks for a statically typed language.

Generics exist for a reason, a modern statically typed language who doesn't implement it is broken. And just like people are productive with PHP, anybody can be productive with a broken language. So the productivity argument is a fallacy. Go is the PHP of statically compiled languages. In fact append,delete,make,copy being native functions is no different from PHP implementing hundreds of native functions in its global namespace. It doesn't look good at all.


> I wrote some code that takes a list of servers to query for some particular thing, and it was easy to write it to do them all simultaneously

In javascript that would be:

  Promise.all(list_of_servers.map(query_server))
Other mainstream languages with similar concurrency primitives (pretty much all of them that either is dynamic or has generics) is similar. I don't think this is an area where Go shines.


That is not what I wrote. You need something smarter to deal with the fact I want the first server returned that replied with a successful response, which is, in general, not expected to be the first server that replied. If you want parity you'll also need to cancel the remaining requests once the successful one has returned.

You still won't have to add very much more stuff, but you're not going to be that much shorter than my Go in the end, either.


As somebody who likes it for work, how do you deal with lack of generics?

My team is starting several new projects in go, where in the past we used either java (and I actually liked java typesystem) or nodejs (and I liked that one as well).

I especialy got used to the functional style of using map/reduce/filter everywhere, and I am not sure if I would be able to continue in this style in staticly typed language without generics?

Or is there a different style I should adopt?


"As somebody who likes it for work, how do you deal with lack of generics?"

By using it in its core domain, network servers, where you don't tend to use generics very much. I've observed that generics seem to be less useful when you're almost always only one transformation away from your data even having just been or being just about to be a simple []byte buffer.

"I especialy got used to the functional style of using map/reduce/filter everywhere, and I am not sure if I would be able to continue in this style in staticly typed language without generics?"

Even if Go had generics it would probably still be a language where you write for loops.

I'm exceedingly iconoclastic on this point relative to the rest of the world: I don't believe "declarative" languages exist. As far as I'm concerned,

    reduce(func(x, y) -> x + y, 0, [1, 2, 3, 4])
is not very different than

    for _, val := range [1, 2, 3, 4] {
        sum += val
    }
Reduce is not any sort of "declaration" of how you want it to be done, it's just an alternate spelling for what may very well be identical machine code.

I am aware of the compositional arguments; my counterargument is that the only language I've used that is slick enough for the composition to end up being useful is Haskell, where the example I gave is

    foldl (+) 0 [1, 2, 3, 4]
where this is fluid enough that composition and factoring out bits of the pipeline is actually worth it. In languages like Javascript, due to the fact it is roughly an order of magnitude more noisy in the syntax, all the code I've seen that is using maps and reduces and folds could be trivially converted to for loops without loss of much more than vertical lines. (Sometimes I even would do the true FP thing and factor out bits of the pipeline, I found it confused people.)

(You can "win" in Javascript by using that sort of style to compose promises together or whathaveyou, but then, in Go, you're always writing at the promise level, so that doesn't matter.)

Basically, when composing two functions together is any harder than x . y, it's just not something people do.

However, your mileage may vary.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: