Hacker News new | past | comments | ask | show | jobs | submit login
Why Go is my favorite programming language (stapelberg.de)
242 points by secure on Aug 19, 2017 | hide | past | favorite | 244 comments



If I were to build a list of the reasons I use go, it wouldn't be terribly different than this one. But interestingly, while I program go every day, I sort of hate it as a language.

You'll note this list doesn't actually have much to do with the language per se, the only point directly related to that is that go has a short list of reserved words (which is true of most languages).

So for future language designers (or existing language designers that want to increase the popularity of their language) it seems like things like language ergonomics, power, etc are less important than having a standard batteries included development stack coupled with out of the box "good enough" performance.


> go has a short list of reserved words

I use go a lot now. However, I must admit I find the use of interface{} "aka empty interface, aka void*" a weird one. It's technically correct, but it's an odd semantic.


I know this is repeated often, but only because it apparently still has to: interface{} is very different from void*. It carries type-information with it. That makes it safe.


No, it's not safe. It's basically a way to disable compiler checks, so it is by definition, not safe.


It is way safer than void * : A void * can be cast to (and then used as) any arbitrary type, leading to all sorts of undefined behavior. On the other hand, the following code will just panic() (i.e. exit cleanly without corrupting memory).

  var x int = 5
  var i interface{} = &x
  *(i.(*string)) = "boom"


> It is way safer than void *

I said "it's unsafe", not "it's not safer than void*".

> (i.e. exit cleanly without corrupting memory).

This makes no sense. If it exits, who cares if the memory of the process is corrupted?

Also, this is the point: it exits instead of the compiler telling you this code will crash before you ship it.

That's the point of static type safety (which Go doesn't provide in this case): it lets you ship code that is provably incorrect and that will not work once deployed (it will exit, like you say).

This is why I said "it's unsafe".


> If it exits, who cares if the memory of the process is corrupted?

People care when memory is corrupted without the process exiting. It is usually better for a program to crash than for it to continue having corrupted its data. The former gives you x-ray machines which sometimes won't start, whilst the latter gives you x-ray machines which sometimes give the patient cancer.

I say better, not best. Best, obviously, is for as many failure modes as possible to be detected before the code is deployed. Particularly if you're programming a machine that can kill people. But in the comparison between Go's interface{} and C's void*, neither language has that option.


> It is usually better for a program to crash than for it to continue having corrupted its data

And it's even better to no let this program get corrupted data in the first place, which languages with a weak type system (such as Go) allow to happen whenever you use `interface{}`.


> I said "it's unsafe", not "it's not safer than void".

I'm sorry, but then you're simply in the wrong thread. You where replying to a interface{} vs. void comment, so that's what you should be talking about.


True, now imagine that program was controlling some kind of device and due to the panic it wasn't able to turn the device off.


Same thing could happen due to bailing out of a function with a return, after checking some condition.

  if (bad_thing)
    return ERR_BAD_THING;

  ... code here to turn off controlled device ...
From my understanding from prior HN discussions, panic is paired with recover; it's a kind of typeless non-local jump and unwind mechanism which can be intercepted. If the device must be turned off, then any panics must be intercepted and code must be executed to put the device in that state.


That's "shitty programmer", not bad language. You can catch panics, and there's a panic safe "val, ok := ival.(type)" assertion.


Memory safe, yes. Type safe, no.


Yes, Type safe. You can not interpret something as a different kind of type via the use of interface{}. Contrast that with void-pointers, which make that so easy as to be a common bug-source.

It's not statically type-checked, yes. That's fine too, in my opinion, but also irrelevant for a comparison with void-pointers (because they also don't provide that).

In summary, interface{} is strictly better than void-pointers. Which was exactly my point. Equating the two is intellectually dishonest.


> Yes, Type safe. You can not interpret something as a different kind of type via the use of interface{}.

Interesting; for some reason, I was under the impression that you could cast an `interface{}` arbitrarily, but from trying it out, you're absolutely correct. (I should definitely make sure to try these things out before confidently asserting about them...)

> interface{} is strictly better than void-pointers

No arguments here; even if for some reason they weren't type safe (which they are, much to my surprise), I'd still agree with you there.


Safe as in nil not even being equal to nil any more, I know I'll sleep better.


nil is always equal to nil. You might be confusing it with comparing a nil pointer to a pointer to a nil pointer, which are not equal.


The nil-interface wart actually does result in comparison issues, and it's something that trips people up all the time:

    package main

    import (
      "fmt"
      "io"
    )

    type Thing struct{}

    func (t *Thing) Close() error { return nil }

    func main() {
      var x *Thing
      var y io.Closer = x
      fmt.Printf("x == nil -> %#v\n", x == nil) // true
      fmt.Printf("y == nil -> %#v\n", y == nil) // false
    }
Here, both x and y are conceptually nil, but y cannot be compared to nil.

Go is a strict language, but it's curiously lax about many things, including this. "go vet" won't even warn you that you're unintentionally wrapping nil in an interface. This goes way beyond just a trivial example like the above one, though: Any general-purpose code that has to deal with arbitrary interface{} values can't just check for nils, but need to do things like this:

    func UnwrapReflectValue(v reflect.Value) interface{} {
      if !v.IsValid() {
        return nil
      }
      if v.IsNil() {
        return nil
      }
      if v.Kind() == reflect.Ptr {
        v = v.Elem()
        if v.IsNil() {
          return nil
        }
      }
      if v.Kind() == reflect.Interface {
        v = v.Elem()
      }
      return v.Interface()
    }
I don't know why Go doesn't let "y == nil" return true here; boxed values are supposed to have the same high-level semantics as unboxed ones, and off the top of my head I can't think of any code where changing the current behaviour would cause breakage.


> Here, both x and y are conceptually nil, but y cannot be compared to nil.

I disagree with the "conceptual nilness" of y. x is a perfectly fine and usable implementation of io.Closer. It doesn't even panic. Having a nil-check (i.e. "does this interfaces contain a value?") return true seems dishonest to me.

I agree, that it was a bad choice to call both the zero-value of pointers and the zero-value of interfaces "nil". But in general, the possibility of nil-pointers being valid values and implementers of interfaces is useful. For example if you have a linked list or graph-structure.

I also asked about it on reddit and got this answer: https://www.reddit.com/r/golang/comments/6sktsr/typed_nils_i...


Your mental model for an interface is incorrect--an interface is just a pointer. A pointer can be nil, but some pointers point to other nillable types. If we paper over this for nil checks, we destroy states that are semantically valid/important. Abstracting as you propose creates more surprising behavior than it fixes. On the other hand, all it takes to avoid the problem altogether is the understanding that interfaces are just (fat) pointers.


My mental model is just fine, thanks; I've written about 70k lines of Go, and I'm perfectly aware of how it works. I'm saying it's a misfeature. interface{} is a leaky abstraction.


It's definitely a leaky abstraction, but not for the reasons you mentioned. Your proposal just adds more leakiness on top of it.


I don't care what we call it, it's still confusing as hell.


Yeah, indirection can be confusing to new programmers, but its absolutely fundamental, so it's better to get used to it than to complain about it.


Except I have 32 years of daily practice and plenty of experience from most paradigms/languages/kinds of software out there. I'm guessing similar goes for some of the hundreds of people who complain about the same thing.

This attitude is exactly why many choose to stay away from Go and its community. The constant denial of any problems and claims that everyone else got it wrong. I don't know where it started, most probably Pike & co; but its not very constructive.


If you think that's my attitude, you don't know me. I have lots of criticism for the language, but pretending a pointer isn't a pointer isn't the solution to people not understanding indirection.


interface{} carries runtime type information in its internal double-word (type + pointer) structure, unlike void*.


Distinction without a difference, talk about Object if you prefer, the only difference is that downcasts are runtime-checked, it remains a huge hole into the typesystem.


> Distinction without a difference

This seems pretty misleading to me. Sure, it's a hole in the type system, but not a hole in memory safety, unlike void*.

(Even the fact that it's a hole in the type system isn't particularly interesting. Most languages have holes in their type systems, by design. What's important is the amount of use it gets, which is of course somewhat-frequent in Go. Same with void in C, so at the type system level, I agree that there isn't too much to distinguish other than quibbling about frequency of use.)


> language ergonomics, power, etc are less important than having a standard batteries included development stack

To programmers under twenty five. And that explains not only Go, but volumes of computing history.


That seems a little unfair. I have better things to do with my programming time than reinvent the wheel every time I need to manipulate common data structures, or make an HTTP request, or query a database, or parse a CSV file, or do some mathematics efficiently, or draw a picture showing the results of that mathematics.

I’m some way past 25 these days, but if there is one lesson I’ve learned about programming languages over the years, it is that a good supporting ecosystem usually is worth more than even quite substantial improvements in the language itself. It’s not that language improvements aren’t welcome — I think some programming languages are much better than others. However, you’re always going to be limited in how productive you can be with a language that lacks comprehensive libraries or good tools or enough people using it to discuss interesting issues or hire a full team of staff, no matter how brilliant the design of the language itself might be.

I don’t know what the worst mainstream programming languages are today, but in purely technical terms surely C, Java and JavaScript all make the shortlist. Compared to many other contemporary languages, these three all lack features, often take a lot of code to get quite simple things done, and are full of easy ways to make mistakes. And yet, in terms of how much useful software has been written in them, they are among the most successful languages we’ve ever had. Why? At least in part, I think it’s because they have three of the most well-developed ecosystems around them.


There could be a valley around 30 where you prefer purity. It's possible though that you soon get tired of language wars and prefer something that makes it easy for you to get things done, i.e. a complete standard library and a good package manager. (And no, I personally don't use / particularly like go but I think your statement is wrong.)


> But interestingly, while I program go every day, I sort of hate it as a language.

I have the exact same feeling. There's a lot wrong with Go, but it makes up for its problems by having very nice tooling (though of course there's problems with that too).


After having coded tens of thousands of lines in Golang for 4 years, there are a list of probably hundreds of grievances I have about the language itself. The problem is that they're generally outweighed by the simplicity, consistency, and clarity of the language. Is the error system terrible? Obviously. Lack of abstract data types? Awful. Is Rust one thousand fold safer and more syntactically powerful by comparison? Sure.

But the fact is, in a world where we as developers often are learning and working in a new language every year or two, time-to-productivity and proficiency in a given language is one of the most important, if not the most important, metrics for a language. And Golang knocks this out of the park with its obvious syntax and great tooling. You can bring in a new junior programmer onto your Golang stack and have then turning out useful pull requests in a week or two, which I can't say for languages like Rust.

I _hate_ much of Golang's engineering, but for collaborative programming I think anyone would agree that it's a highly productive language.


Why learn a new language just to learn a new language for production stuff? I looked at at switching to Go from Java for my flagship product. I couldn't find enough compelling reasons to switch. It didn't offer enough benefits to outweigh the benefits of Java + Spring Boot. As a result, Java it is.

Now for a new product that I might sell as traditional installed software, Go makes some sense here since it simplifies install. My clients wouldn't need to install and maintain the VM.

In the end I wonder why switch to a new stack just because? I understand learning the languages to see if they are better tools. I understand learning for the sake of learning. But why bet a business on a new language just because it's cool?


My team just chose golang instead of java or dotnet core for a new crud app. I'm not especially fond of go, but mean length of feedback loops are worth it (so far). We have a bunch of tests, and they all run in a few hundredths of a second. Same coverage in java is usually several seconds at least. Often up to 30s if running tests with maven.

Standing up the app is also instantaneous. Spring boot apps with hibernate often take at least ten seconds. In prod this doesn't matter. But a cheap app start means integration tests are cheap. An fs hook runs both unit and integration tests every time the code changes.

ps. all the things people hate about go are true


There are lighter options in java world, my dropwizard server with JDBI starts in 1.2sec.


I'm genuinely unsure if this is a joke. If you're running that on a modern computer, your server is spending billions of clock cycles starting up. What on Earth is it doing? :)

If I write a Go server, I'm unhappy if it takes more than 0.2 seconds to start.


Depends what your server is doing, java app binded to http port will take probably same amount of time.

My dropwizard server contains almost all possible batteries: ssl, logging, http filters, static content, metrics, DB connection pooling, static content serving, all kinds of URL parameter parsing and URL routing, DI framework, ORM, thread pooling. I think it just inspects and initializes all this data structures in memory, load libraries and classes, etc.


> My clients wouldn't need to install and maintain the VM

Why should they?

One can always deliver everything together.

Not much different than static linking.

Also there are AOT compilers and with Java 9 we are getting a linker to create customized JREs.


I'm waiting for the 9 features. That should make things easier. Since I'm targeting small physician practices, I need to make everything as simple as possible. I've even toyed with Raspberry Pi as the install device. From what I've read, Go is a good option for this.


I noticed as well that I didn’t mention a single language feature, even though I do actually like many :).

I agree with the sentiment you expressed: the overall experience when using a language matters to me much more than individual language pros or cons.


> the only point directly related to that is that go has a short list of reserved words (which is true of most languages).

The number of keywords of a language is completely unrelated to its complexity (see Brainfuck or Lisp).



SAP ABAP syntax includes:

+ database retrieval and manipulation as a 1st class concept. ABAP doesn't require a 3rd-party ORM and therefore, SQL statements are 1st class syntax.

+ GUI capabilities as 1st class syntax (user interface elements for forms, lists, grids, visual reports, etc)

Golang core doesn't have those, so it understandably doesn't need extra official keywords to address that functionality.

SAP ABAP has more keywords that's typical for a 4GL type of language. Like other business-domain 4GLs, the complexity isn't the language syntax -- it's navigating the gigantic data model to find where important information lives. (e.g. Out of 10,000 tables, where does the sales invoice live? If an invoice is paid, where is that status field? And to make it harder, many of the database column names are German instead of English ... like AUGRU[1] for "auftrag grund" instead of English "OREASON" for "order reason".)

If Golang language spec was revised to include a 1st-class ORM and GUI & report builder into its core syntax, it would be a more apples-to-apples comparison. Golang can have less keywords, because it has less features.

[1] http://www.se80.co.uk/saptables/v/vbak/vbak.htm


> Golang can have less keywords, because it has less features.

So, you are saying… because it's less complex?


No. I don't think Golang is "less complex" because it has less features than ABAP _if_ you plan to use Golang to write GUI applications that interact with databases to track enterprise data of sales, purchase orders, manufacturing, inventory control etc.

"Complexity" is not a useful label unless you look at what you're actually building:

- If the goal is to show "hello world", yes Golang is "simpler".

- If the goal is an ERP system, Golang is way more "complex".

Between those 2 extremes requires analysis on a case-by-case basis.


This is the same reason I rolled out Salesforce for a couple workflow apps for a few teams in our company.

I could bootstrap a .Net/Java/whatever app to do the same thing, but our team is swamped with a backlog years long - I could only afford a couple days to develop and release this so a dozen Force.com licenses ended up saving tons on development and ongoing maintenance costs.


>But interestingly, while I program go every day, I sort of hate it as a language.

I would be interested in asking you to put some of these thoughts down. This can be contentious as it's matters of taste (i.e. I don't want others to reply to you defending it), so if you wanted you could email me - my contact is in my profile. Just a few thoughts -- i.e. what you had in mind when you wrote that -- would be really helpful for me.

What makes you hate the language?

Thanks so much for any thoughts.


I really dislike Go as a language, it has very few means of abstraction and it feels depressing that people think you have to throw out decades of PLT research to achieve perceived clarity like this.

That said, these reasons are almost all linked to tooling, which is something that I have to admit Go gets right, but they're not intrinsically linked to the language itself and its feature minimalism. I wish there were better languages that had such nice tooling, but unfortunately not all langs have the luck of being backed by Google.


Re: getting tooling "right" and that driving adoption/popularity.

I'll argue that Java and the JVM are very similar in this respect. Few will argue Java is a "good" language and the JVM has many shortcomings.

However the ecosystem of IDEs, JVM tools, and decades of big company investment (Sun, IBM, Oracle) have created an amazingly productive environment.


Yes, my impression is that Go was created partly to be used in corporate environments to replace Java with a less verbose language that scaled well, and it seems to be doing well in that regard.


Sadly, it ends up far more verbose than Java when you have (as I did after trying to port a project from java to go) over 200 copies of the same observable, sorted, copy-on-write set implementation, because Go doesn’t have generics. And then you change one thing in one place, and gotta change it everywhere again.

No thanks.


Surely you could have used interfaces for this case, no?


And how do I get the same type out that I put in? I'd end up with Java 1 style programming, no generics, and having to cast atuff from Object/interface{} everywhere.

interface{} is like Object, if it even exists once in your code, it's broken.


> And how do I get the same type out that I put in?

You can only get out the same type you put in. Presumably in your code you know that collection of Foo objects contains Foos, so you can just do:

    if foo, ok = collection.get().(Foo); !ok {
      return errors.New("expected a Foo")
    }
Write a few wrapper functions and you're done.


So, we’re back in Java 1.0, and using Object and just casting back again?

Seriously, this is why generics exist. I want to write it once, use it everywhere again, and want to have the compiler know if I made a mistake.


A couple reasons that wouldn't work well (there may be more, I haven't thought about this much):

1. Using an interface would nuke your performance. Data structures where every data structure operation requires one or more vtable lookups on items in the structure can really hurt your time and space performance. To get good performance, you need true type-level generics so the compiler can specialize at compile time.

2. Anyone could put anything that followed the interface in the data structure, even if it was of the wrong type. To get any form of static type safety, you'd still have to define a wrapper type and a bunch of functions for every type you'd want to put in the data structure. You could save a bit of work by re-using your (slow) code you wrote generically using interfaces.


Ultimately, programmers fall in a bell curve. Most languages which benefit extensively from that research target people on the right of that bell curve. Go, with its lack of complicated mechanics targets the middle of the bell curve.

I don't have the luxury of working exclusively with people on the far right of the bell curve, so I'll end up picking Go with its simplicity for most projects. I can be assured that almost anyone can pick up code written in Go, and be productive much faster as a result.


> Go, with its lack of complicated mechanics targets the middle of the bell curve.

No, it targets the less experienced - interns, as the language creators said.


I don't think Go targets the less experienced. Could you provide a resource, where the language creators have stated that Go targets interns?

Go is a safe programming language, but it is not simple. Go has very rigid rules.

I don't see any difference in complexity between programming in C and programming in Golang. Programming in Golang may even be harder than C.

If you format your code wrong, Golang screams at you.

If you import a package and never use it, Golang screams at you.

If you redefine a defined variable, Golang screams at you.

If you don't use a variable you defined, Golang screams at you.

C is much more forgiving :).

Golang makes dynamic memory management safe, but in nowhere easy. You still use the good old void* via an empty interface. For an intern, garbage collection doesn't matter, an intern is intelligent enough not to leak so much memory so that it will get noticed :).

I sometimes think Golang resembles the early versions of Java. Creating a safer C-like language, with great ideals. With Java the complexity kicked in after a while. Golang still resists the urge to please everyone.


> I don't think Go targets the less experienced. Could you provide a resource, where the language creators have stated that Go targets interns?

"They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt." - Rob Pike


> C is much more forgiving :).

I think this is confusing being permissible with difficulty. Because C is permissible, it makes writing correct code in it hard. The fact that the Go compiler has a (relatively) simple type system and is able to point out mistakes like the ones you mentioned makes it much easier to write correct code.

I'd also just like to point out most of the things you list about Go won't cause a crash or undefined behaviour if you were able to leave them in anyway.

As pointed out elsewhere in this thread, interface{} isn't the same as void. void will let you reference anything as a type unsafely leading to undefined behaviour. interface{} carries type information, and while it does cause crashes, it doesn't lead to undefined behaviour.

Also, how is memory management in C easier? Leaking memory is the least of your worries, you could double free, null ptr access, invalid free, have dangling ptrs, etc. Lots of these things are taken care of by Go's GC so you don't have to worry about it.


There is a Go talk where Rob Pike states that.

EDIT:

Found it, https://talks.golang.org/2012/splash.article

"It must be familiar, roughly C-like. Programmers working at Google are early in their careers and are most familiar with procedural languages, particularly from the C family. The need to get programmers productive quickly in a new language means that the language cannot be too radical."


You just gave some reasons why correctly programming in Go is easier than in C, like paint by the numbers or training wheels (restrictions) versus a blank canvas; it's easier to make mistakes in C, ergo harder to program in. Golang screaming at you is like having a coach.


The compiler complaining when you do things wrong makes it much easier than C to write correct programs, if anything.


Can testify that other people do limit the tools you can use. I was on a project that I couldn't use even use interfaces, streams, classes, or generics because the other programmer was incapable of understanding how they worked. I eventually just switched to a tool that did the work we were working on to solve the problem without programming because that guy despite having a masters degree in CS and ton of certifications was incapable of understanding anything remotely outside of procedural programming.


> ton of certifications

That gave it away.


> I wish there were better languages that had such nice tooling

Have you considered that the reason why go has such great tooling is precisely because of its desperate grip on simplicity and non-configurability -- the very things you might call upon as why it's "bad".

Maybe this correlation is more than coincidental.


While I neither love nor hate Go - I'm really confused about "Go gets tooling right". Is it mostly about the built-in gofmt and compiling to binary? Dependency management is far from right, for example, and so are stuff like hot code reloading, remote debugging, containerized development, etc. How does Go get tooling right compared to, say node/npm or java?


Tooling in regards to formatting: I guess you get to appreciate it when using gofmt automatically with your editor, eg. with Go extension for Visual Studio Code or vim-go.

Turns out pretty much as he says (see given example at play.golang.org). You just type in the style you always have, but with the certainty that in the end it will be the same as the other's, easy to read, easy to maintain, and uncontroversial in terms of formatting. You could agree on google-java-format, I guess. But also potentially waste plenty of time on the decision itself :-) compared to a dictate and tool originating from the language itself.


Google doesn't invest heavily in Go. It almost certainly invests more in JS, Python, Java, and C++. I think the difference is philosophical--Go doesn't pretend that every obscure edge case deserves equal support to the main case, and so its tooling is much simpler.


I'm not sure where you get your information from, but Google definitely invests a substantial amount in Go.

- Paid some of the most celebrated engineers to work on it full time. - Support it as a first class language in GCP - Support it as a first class language internally

If you want to see a language Google doesn't invest much into, look at Dart


Even dart has substantial investment. Look at flutter, the new cross-platform ui toolkit for dart, and its use in Fuchsia.


Google pays a small team to maintain the language, but developing the language is very likely not a business objective in remotely the same capacity as .Net is for Microsoft or even Swift for Apple. It's not even a major headliner for Google's I/O conference. I would like to know where you're getting your information about Google not investing in Dart, because last time I checked, Google appeared to be investing considerably in Dart (this was back before the Dart vs TypeScript battle was settled though, so perhaps Google pulled up its investment).

At any rate, Go's tools don't require significant investment because they are designed for simplicity (there is no package repository, no language-agnostic/fully-imperative build scripting language or project metadata files, no bring-your-own-unit-test-framework, no docstring syntax, etc). Go tools err on the side of supporting too few use-cases, where Java, Python, .Net, C++, etc build tooling typically emphasize explicit configuration over sane defaults.


Does someone want to give a reason for down voting this comment? There isn’t anything controversial here. For myself, lack of genetics are enough reason not to use the language. My personal style relies a lot on them and I don’t see myself sacrificing that power for above average tooling.


> For myself, lack of genetics are enough reason not to use the language.

The typo/autocorrect here turns this into a much more controversial statement...


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.


The "easy to learn" argument is getting old. If the cognitive load never decreases, that's one thing, but initial ramp-up time shouldn't be a large determining factor. The MVC pattern, ADTs, functional programming, and so many other useful concepts were foreign at first, but have a substantial impact on how you think and work. With the exception of channels, Go doesn't add much when compared to other languages. Maybe that's a pragmatic choice, but it feels short-sighted to me.


With the exception of channels, Go doesn't add much when compared to other languages.

It doesn't add things, it takes them away, notably exceptions, inheritance, generics. I disagree that's short sighted, it's precisely for long term maintenance that it becomes important to have less ways to do things. You may not agree with the choices, but they are not only about being easy to learn, more about being easy to read.


People just end up inventing idioms to handle those, anyway. Go's nil-check error handling is a prime example. That's a beautifully solved problem with ADTs, but it's impossible without generic support, for starters. Runtime errors, abound!


Go can handle errors in a very deterministic way, and it can easily recover from a weird panicked state. If someone's Go code has "runtime errors abound" then they probably didn't RTFM ;)


Ah, so when I think of deterministic error handling, I think of compile-time enforcement, like that provided by a Result or Option type. Those can be ignored too, though, although the effort to do so is a little bit more explicit. :)


> It doesn't add things, it takes them away, notably exceptions, inheritance, generics.

s/exceptions/error handling/

What Go proposes is awful for a modern language.


Go has error handling, it doesn't have exceptions for non-exceptional error cases.


Go has functions with multiple return values. That's not at all the same.


I didn't talk about multiple return values, did I? Every language has error handling support, some languages hijack an exception mechanism as a control flow path for non-exceptional error states. Returning error values is more ergonomic than exceptions, but Go's lack of sum types makes this slightly tedious (still better than exceptions).


Right, I jumped ahead; multiple return values is the how Go returns error values, it's not error handling itself. I don't like exceptions much either, but sum types / ADTs are just so nice for this sort of thing.


I agree that sum types are nicer, but I don't see how they constitute error handling in a way other return mechanisms do not. The difference isn't categorical, it's ergonomic.


I'm starting to find it weird that things like "error while passing string as int" trigger an exception rather than return an error.

There are always error cases to check when handling user input. It's a natural part of the program flow, not really an exception.

I would expect an 'exception' to be something like out of memory or disk corruption.


Presumably you mean "user provided a string which was supposed to be decodable as an int, but was not"? If so, then yes, this should be handled as an input error and not as an exception (programmer error). I don't know if you meant this as a criticism of Go or not, but you should find that Go programs almost always return errors (as opposed to panicking) under such circumstances.


Sadly our entire industry is based around being short sighted.

Quick to learn is only important if you have the lack of patience to spend the time to learn something you'll be using for years.


Our industry is hugely based on illusions and misconceptions. There are only few places on earth where people regularly rebuild the skyscrapers to build taller ones. The IT industry simply forces you to re-learn the same old paradigms in a new package just to gain 0.1% of something we cannot even define as an improvement.


This is what I most dislike about Go: it's a modest improvement. It could have been much better, with a higher-level and less verbose syntax and allow metaprogramming (e.g. like Nim).


One thing I've been looking at lately is the various strands of engineering (civil, electrical, mechanical). I've been looking for common threads and general principles that apply to software engineering that otherwise haven't been.

A part of what inspired that search is what you discuss: a huge amount of rework. Tools that shift like sand dunes. Many principles and best practice based on "this is what worked for us".

I can't seem to shake the feeling there must be a better way.


The fundamental difficulty is the blue sky nature of software. You can literally code anything you can imagine. Language semantics, algorithms, architecture, it's all up for grabs, it's all cheap, and the applications are unlimited. Compare with traditional engineering disciplines where you have massively constrained costs, materials, and even goals.

What would civil engineering be like if instead of the immutable laws of physics you had a system designed from the tiniest quark up to the largest galaxy by humans, and if that design was subject to change on a whim?


I think that attempts to unify traditional forms of engineering with software engineering are doomed to failure, because they're so different as vocations.

For example, the design and construction stages are indistinguishable (any sufficiently detailed design of software is effectively an implementation of the design). Normal engineering is not the same, and is likely one of the reasons that software prototyping often become the final product (which is definitely not true for traditional engineering). Fields like electrical engineering that use software engineering quite heavily are only similar to traditional engineering because of the traditional components of the other engineering discipline (electrical engineering requires circuit-board design that is distinct from fabrication, and prototypes are rarely promoted directly to the final product).


That's true. I don't think that there are major things in those disciplines that are directly applicable in a timeless fashion.

My main goal is to find out how these disciplines came about. How exactly did they settle upon their body of knowledge such that they can produce reliable results in the way they do. Not so much what those methods are, but rather how they came about. What is the common thread there and how, if at all possible, can we use that accelerate the same maturity in software?

Maybe it's a process that has to run its course? Maybe at 80 years old, if I live that long, I'll look on a very different kind of software development.

With that said, I also have Fred Brooks whispering "no silver bullet" into my ear on the other shoulder.


Maybe the other engineers would love to be able to do more rework, but since they deal with hardware, changing things is a lot more expensive. Why do you think that their ways are superior? Construction projects too run way over budget and sometimes even fail, just like software.


You make a good point. Maybe their ways aren't superior - I didn't consider this. In that case, perhaps the issue isn't because we need to be more like other engineering disciplines but less like.

I'm feeling for answers. I'm not saying I know what we need. I am, like I think everyone else is, still in the observation stage looking for hypotheses.

I did find evidence based software engineering. This offered some interesting papers. I recommend this. There isn't much and it's far away from a cohesive theory but hopefully we can get there, as a field, soon.

If someone is further along, or has some ideas, I'd love to speak with them.


Quite common in fashion driven industries.


Architecture is thousands of years old. Programming as we know it is maybe 60.

We're still figuring out how to do things correctly. Maybe we just figured out how to build a log cabin, but now some people are going back to mud huts because they're simpler.


Lot of new languages try do to everything which is imo a big mistake.


Huge success of mongodb was due to "easy to learn" advertisement, paired with getting shit done and rewrite later agile trend, and web scale.


Is this a positive or negative example?


It matters for large teams and when you got hundreds of languages to choose from. I am sure Haskell is great but after a couple of weeks studying it I realize I don't have time for something I don't know if will pay off or not. In contrast with Go you can see benefits almost immediatly


Two weeks is a tiny investment to properly evaluate a language. Haskell is tripping you up because you're likely new to proper FP and very strongly typed languages. Pushing past two weeks, even if you don't use it, will make you a better developer, and the next FP or strongly typed language will come more easily.


You probably mean statically typed, not strongly typed. The distinction is clarified in "What To Know Before Debating Type Systems":

https://cdsmith.wordpress.com/2011/01/09/an-old-article-i-wr...


I didn't, actually! I don't know how else I'd express it, but I'm thinking of Rust, Haskell, etc's "step beyond" plain static typing with sum/ADTs, pattern matching, and exlusion of null. A seemingly small detail, but it does feel like it makes the type system more deterministic and "stronger", in a sense.


> There is a cost to introducing an abstraction layer. Go code is usually rather clear, at the cost of being a bit repetitive at times.

Go programmers say this a lot and every time I see it I wince. We've had all sorts of flights of fashion and fancy in the programming world, but one observation has emerged that seems closer to fact every time we test it: more code is more bugs. The more code you write, the more chance there is for bugs.

And so it's so confusing to me why Go programmers simply discard this information, universally accepted as it has come to be. "The repetition is simple," they reply, "and of course abstractions have cost."

So what is the cost? Because I can tell you the state of affairs right now. I find Go code exhausting to debug, because there is effectively no universal way to handle errors other than to copy-paste if-nil statements. Occasionally, slightly different error handling logic creeps in and it's so tempting to start pattern matching the whole block of code and miss these subtleties.

This list's discussion here... Well sometimes I get the impression that Go programmers are more interested in never having the opportunity to make a conscious mistake, in exchange for making lots of unconscious mistakes.

Go has popularized a mode of writing code where not only are abstractions unwelcome, but they're nearly impossible. As such, it is quick to learn the syntax. It's not really any quicker to learn how to write good robust multi-threaded code though. I still think the Java standard library consistently delivers a better result for equivalent work, at the cost of learning and extra (standard) library.

I just don't understand why anyone appreciated go's design space outside of engineers-turned-architects trying to staff a massive tech org with engineers they don't think very much of and have no desire to train.


As Sandy Metz once said, "A little duplication is far better than the wrong abstraction."

After a decade of OOP indoctrination and misuse, we see the results of this.

> Go has popularized a mode of writing code where not only are abstractions unwelcome, but they're nearly impossible

This lends me to believe you actually haven't written any go code for yourself. This is the same thing every OOP-indoctrinated developer (Usually Java or C#) has said before. I came from those languages, and this statement is categorically false and completely unfounded in reality.


> After a decade of OOP indoctrination and misuse, we see the results of this.

Sure, but that's OO's fault and the lesson is not "abstractions are bad" but rather, "OO's good at domain abstractions and bad at universal abstractions."

The takeaway should not be to discard the last 12 years of advances in computer science and call it quits with a bad copy of Erlang's concurrency model and a weak version of C.

> This lends me to believe you actually haven't written any go code for yourself.

I've written about 5000 lines. So not a ton, but enough to have shipped Go to prod and be capable of reading it.

> This is the same thing every OOP-indoctrinated developer (Usually Java or C#) has said before.

Go is more OOP-focused with its weak interface{} methodology than anything I promote or have used joyfully in the last 6 years. Even the most cursory examination of my presence will reveal that.

Please don't put words in my mouth to tidy your argument.


You can't write a generic map function for lists. The lack of this abstraction alone should be damning. Even rudimentary functional programming is hard in Go.


> "A little duplication is far better than the wrong abstraction."

A little exploration is better than a false dichotomy.


Integer loops over length should be enough for everyone. Especially when poor numerical method error handling has bugged sort implementations for most of my life.


> As Sandy Metz once said, "A little duplication is far better than the wrong abstraction."

like writing 500 * if err != nil { return err } is an average Go app? A little yes, but this isn't a little.


like having your IDE cover the other 100 some-odd places of boiler plate such as writing getters and setters, and implementing comparable and hashCode and every other piece of insanity? Also, I much prefer to handle my errors where they happen in the code rather than do Pokemon try/catching. Sorry, the if err != nil horse has been beaten to death already.


> like having your IDE cover the other 100 some-odd places of boiler plate such as writing getters and setters, and implementing comparable and hashCode and every other piece of insanity?

What is insane is believing returning errors is actually handling them, it is not, you're just passing the burden on the caller.

Second, Go isn't free of all the bullhshit you described so I'm not sure what is your point, that you don't have to write getters and setters in Go? lol, off course you do have to.

> Also, I much prefer to handle my errors where they happen in the code rather than do Pokemon try/catching

Who cares, go back playing Pokemon since apparently that's the only thing you can think off and stop being an hypocrite. What do you think panics are? yes, it's an half-baked exception system, like everything in Go, a language designed by people who clearly didn't know what they are doing, for people who don't.

> Sorry, the if err != nil horse has been beaten to death already

Yes, and don't worry, people will keep on beating that horse, because it was designed by people that clearly don't know what they are doing.


Go is a uniquely rude language which both has over a dozen numeric types (seventeen from my reading of [0]) and also zero code reusability. I can't think of a better way to ruin any chances I might have of avoiding numeric bugs.

[0] https://golang.org/ref/spec


Regarding your last paragraph, it's a reflection of the state of the industry. The vast majority of "software engineers"/"full stack developers" can't be bothered to learn new skills or improve their existing ones, so any popular programming tool is stuck catering to the least common denominator.

Do you carefully review your own code? Do you voluntarily learn any new skill beyond "blog post intro tutorial" level? Do you think about the consequences of a change you make beyond the immediate need it addresses? Congratulations: Regardless of talent, you're already better than ~90% of professional programmers. You're a "10x developer" by virtue of the fact that by a reasonable baseline of quality the remainder are "0.1x developers" or worse.

I don't think that Google is wrong to focus on mitigating the damage that the majority of engineers will inflict on a codebase. In fact it's depressing how right they are, and what the realities of software engineering look like at scale. It confuses me though that small teams select tools built to solve those problems.


I talk to a lot of people new to the industry, both by way of my employer and my via University.

I have a hard time being this cynical. I think post-educational market forces drive this trend, not the personal inattentiveness that I sense (perhaps unfairly, please correct me) that you blame.


> Do you carefully review your own code?

Do you have any resources for getting better at this? I don't get a lot of chances for other people to review what I write (yeah believe me I know..) and am looking into better ways to make sure I don't release shit.

I have a decent amount of testing automated for a majority of my projects but that's turning into an extra job on-top of my already demanding job.


Here are some of the techniques that I use for C, C++, and C#.

Read every checkin twice before committing it. I find and fix many bugs by doing this.

Keep a log of errors and problematic APIs. Periodically review your code for methods and idioms that you tend to misuse. I find it easier to spot one incorrect call to an API when looking at all uses of it.

Enable all compiler warnings and use warnings as errors. It is easier to spot regressions when the build is normally silent. If a project has a noisy build then use the normal warning level and enable additional warnings over time.


It sounds like you're already doing a good job of trying to not ship garbage.


I love the error handling in Go. Every other language I've used led to the inevitable and useless "An error was encountered" message.

Go is the first language where I can actually access the original socket permission error because it was actually passed up.


> Go is the first language where I can actually access the original socket permission error because it was actually passed up.

Now try to trace them as easily as exceptions. Oh wait, you can't unless you wrap Go errors into some struct from a library that isn't in the std lib therefore everybody has different systems to trace errors /s

i'll take exceptions over this (which go has, panic/defer). error is just a convention, it's not an error system.


I'll take Either where I can guarantee I know what I'm dealing with and that it's dealt with rather than the honors system Go offers.


Go is basically using multiple return values as a half baked Either type, only you're on your own if you want to pass it over a channel or store it anywhere.


Sadly go can't even half bake a sum type suitable for this work without generics.


Pretty much every language has this: Java, Python, Ruby, Haskell, OCaml, C++... The only major language that I can think of that doesn't have a standard error propagation mechanism is C.


Have is different from use, in practice. I should say that In the real world Go libs actually pass the errors up while my experience with other languages has been shaking my head at the useless errors that I get back from the libs.


Well I won't deny you this experience, but I do think maybe you've been lucky in which parts of the stdlib you've worked in.

Because I felt nothing but frustration at most libs I worked with. I (as others before me) ended up grepping error strings.


You just described exceptions.


> Every other language I've used led to the inevitable and useless "An error was encountered" message.

I can't think of a single language except C where this has been a problem for me. What are you referring to?


What's weird is that what they're describing is actually really tricky to do reliably in Go unless you totally understand every library beneath you.

Much bad can be said about checked exceptions, but they certainly helped with that problem...


>This list's discussion here... Well sometimes I get the impression that Go programmers are more interested in never having the opportunity to make a conscious mistake, in exchange for making lots of unconscious mistakes.

A certain demographic can't stop waxing erotic about "being in the flow" and so love nothing more than churning out 1000 lines of mindless boilerplate, for this chunk endless if-nil checks are a feature not a bug because it's rote and adds to the line count.


When Java was first introduced, the world was abuzz about this cool new language which you could "write once, run anywhere". It took some time, but as it grew in popularity, articles started appearing about how much Java sucked because it was slow and bloated, required a ton of boilerplate code, and eventually because "write once, run anywhere" turned out to be a myth, along with a boatload of other reasons. The honeymoon wore off, and legions of Java-haters were born.

Perl suffered a similar fate. When it came out unix was just surging in popularity with the internet boom and a lot of people were thrilled to have a single language you could learn which combined the features of common command-line tools like sed and awk, and that was a "real programming language" that was more powerful than shell scripting, and which grew to have a ton of useful libraries in the form of CPAN. Years later, and Python and Ruby started getting popular, the "Perl sucks!" mantra sprang up and the once-mighty Perl shrank before the upstarts.

Ruby and Python are getting their turn now, and I'm starting to see some people expressing hate towards them as well, though it hasn't quite reached the pervasiveness of Java and Perl hate yet.

Go was next. People were excited about this cool new language from Google, a place filled with great engineers, and from the mind of Rob Pike, of Unix and Plan 9 fame. It was supposed to be like a simpler and more elegant form of C. What's not to like. Well, the replies to this post are showing that for some the honeymoon is already over.

Other languages had their day in the limelight, only to wind up being hated: C++, Lisp, Fortran, Cobol, HTML, Javascript.

Bjarne Stroustrup observed that "there are two types of languages, the ones everyone complains about, and the ones nobody uses."

Whenever some shiny new language comes out, promising to solve everyone's problems in some domain, and people start jumping on the bandwagon and singing its praises to high heaven (which seems to happen ever couple of years), I try to take a deep breath and step back. There will likely come a day, before too long, when they too will be subject to hatred and scorn, just as all the other popular languages before them.


> Go was next. People were excited about this cool new language from Google, a place filled with great engineers, and from the mind of Rob Pike, of Unix and Plan 9 fame. It was supposed to be like a simpler and more elegant form of C. What's not to like. Well, the replies to this post are showing that for some the honeymoon is already over.

As someone who has paid attention to this since Go was released, there never was a honeymoon. The complaints in this thread have been the same exact complaints people have been lodging against Go since 1.0 was released.

What you're seeing is very simple to explain. Some people love Go. Some people like Go. Some people dislike Go. And some people hate Go.


You could say the exact same thing about every computer language, but it would miss the forest for the trees.

Certainly from the very beginning, there'll be some subset of the relatively few people who've actually tried a new language who don't like it for some reason or another, or object on legitimate technical grounds (the border between these two types of objections is murky).

As the popularity of the language grows articles are written, starting in the specialized press and (if the language is lucky) ending up even in the popular press, getting even non-technical managers excited and using the newest buzzwords.

With time, the recognition and consciousness of the language's deficiencies become more widespread among a wider portion of the programming population, and articles and discussions of such complaints become more widespread.

In the end, such complaints may become mere truisms, and the majority of the population just parrot the truisms and stereotypes while having only a superficial or even non-existent familiarity with the language that's criticized.

Of course, you could say that such things were going on all along, but it would be missing the broad ebb and flow of language popularity and people's reactions to them.


Right. I understood that point. I'm saying that I think you're wrong. There has been no ebb and flow from where I'm standing. The criticisms against Go really haven't changed much, and neither have the people making them. On the flip side, Go has been becoming increasingly popular, and I see no signs of it slowing down.


It's not an ebb and flow in the criticisms but in their adoption and the awarness of them in the wider programmer population. It's that awarness that ebbs and flows.


> "there are two types of languages, the ones everyone complains about, and the ones nobody uses"

Of course Bjarne would say that. The reality is, there are some languages that people use a lot and don't complain about nearly as much. Some languages are just actually worse to use. http://andrewvos.com/2011/02/21/amount-of-profanity-in-git-c...


So of course, going by the logic of linking that article, we're all wasting our time and should just be using PHP?


Pleasantness of use is only one dimension. I think it makes sense to use C++ sometimes even though it's (evidently) relatively unpleasant.


I've been using Go for a while, and am frankly amazed at the quality of the tooling.

I'll add something others haven't mentioned... the profiler produces an absolutely amazing graph of the run-time call tree[0]. This makes it incredibly easy to not only see where the code is spending its time, I can easily the context, and where else time is being spent. I recently sped some code up (5x!) using this.

0: https://blog.golang.org/profiling-go-programs


I think regardless of how each one of us sees Go, its adoption among DevOps (Docker, K8s), Apple and Microsoft means that just like with C and JavaScript it will become unavoidable to use it for certain tasks.


I'm not sure that I follow. To me, it sounds like someone saying we need to program in C because we use git whereas we actually interact with git through the interface they've given us, not through its source code. Even if Docker and K8s become ubiquitous, I see no reason programmers taking advantage of these to also program in Go.


It means that anyone that is working on DevOps, while having Docker/K8s on their employer infrastructure, might eventually be asked to write Go for whatever reason.

Given that they are written in Go, and as far as I understand it, the way to customize them also requires using Go.


Adoption from Apple? If you mean on their internal services, then that's irrelevant as to the rest of us "having to use it".


They have quite a few open positions asking for Go knowledge.

No idea how they are using it.


Yes, I meant it's not like Apple is forcing it on external developers though, like e.g. they "force" Swift.

Google could do that (if they adopted Go on Android), but I think they went with Dart instead IIRC.


> Yes, I meant it's not like Apple is forcing it on external developers though, like e.g. they "force" Swift.

Sure, but at the same time it creates awareness in other companies that Go is a good bet that they might adopt as well.

> Google could do that (if they adopted Go on Android), but I think they went with Dart instead IIRC.

They went with Kotlin.

Dart is still looking for a killer application beyond supporting AdWords, lets see how far they go with Flutter or Fuchsia.


Too bad


I'm kind of wondering about why is there no production ready JavaScript/TS to exe compiler that packages all dependencies and creates a single executable - like go.

With the amount of mind share that js ecosystem has, I thought that would be a thing.

The keyword being "all dependencies"



very cool! is this production ready ?



Wow this is extemely close to my own reasons for having a preference for Go. Very well articulated. The clarity of Go code can not be empasized enough. To be fair my favourite languages are Julia and Swift but that neither can really math Go in clarity and simplity.


I know a guy who used to teach Haskell at a university who now runs a development shop at a startup that uses Go. From I recall his main reason for choosing it was to hire cheaper less experienced developers. I remember talking to him about Go and he remarked something like: If you want to clean modular code don’t use Go.

Not to disparage less experienced developers but I think teams of developers of any experience level need to have code governance and oversight regardless of the technologies and that a good team with good practices can create good code bases even with more complex and expressive languages. I know another colleague who did this with Scala and was able to properly mentor more junior developers by leading by example. I have not used Go. I have done and lot of Java and a bit of Scala and have many times leveraged generics to create a very high degree of reuse. Without them clearly you get a lot of boilerplate code which makes a codebase larger which leads to another type of complexity in my opinion. So the question is which scenario increases your codebase complexity and that probably boils down to what domain you are developing in. I explore some ideas relating to that tradeoff here [0]. Go has a specific use case that it targets which I believe is services and certain aspects of concurrency.

Clearly the Go language and environment have value in the industry, however, as a language it offers little for people who want to have an opportunity grow and learn about more advanced concepts wrt to PLT and CS in general. I have a friend who is a Go fanatic and I try to encourage her to push her limits, but she feels and she can bang out service level code very quickly and she can as she is quite talented. Of course you can do that with Spring Boot as well. Regardless of your language you should always be trying to grow as a developer otherwise you risk becoming obsolete.

To put it bluntly and I may get downvoted for this I feel Go is the “Rise of the Expert Beginner Language”. [1]

[0] http://www.elegantcoding.com/2012/02/software-reuse-complexi...

[1] https://www.daedtech.com/how-developers-stop-learning-rise-o...


"The Rise of the Expert Beginner" was a great read. I do see the parallels to the tone and tenor of some arguments in favor of Go.

One thing I wonder about is a seeming complementary anti-pattern, the "Expert Only Language". Perhaps C++ is the only language that truly fits this description, but one can see shades of it in Haskell, Scala & Rust. To a limited degree, Bash and SQL exhibit similar qualities, because people can use them for years but barely know them.

These are languages where a certain confusing richness is accepted as the cost of doing business, and where a long period of familiarization is assumed to be necessary before doing basic things.


I wouldn't list the standard library as a great strength of Go. While some parts of it are quite good, some others are terrible. Notably, logging and argument parsing are pretty bad. Compare Go's "flags" and Python's "argparse" for example. And Go's "log" and Python's "logging". The Python versions are not perfect but are at least quite usable. In Go, I have yet to see a project with more than 1k lines of code that won't use a third-party argument parsing and logging package.

For logging, each package will use its own logging mechanism. Sometimes, you are lucky and you can pass your own logger (with a random interface as the interface is not part of the standard library either). Sometimes not.

For a language born less than 10 years ago, this is a pity.


What would convince an avid Python user to switch to Go st this point? Let’s narrow down the scope to an API backend to be more specific (isn’t that’s where Go’s performance thrives?)


- Real concurrency without having to deal with spawning multiple programs that communicate over some higher level process

- Good concurrency primitive (channel), although asyncio Futures in Py3 aren't that bad either

- Strong typing

- Easy byte-level manipulation

- Extremely easy to learn

- Simplistic error handling compared to exceptions (there are problems with this I won't go into, but it's easy to learn at least)

- Amazing tooling (gofmt forces your codebase to be consistent regardless of who is writing it)


I was an avid Python user for roughly a decade, and I switched to Go. IME, writing it feels a lot like writing Python, but I feel much more confident that the code I write will run the way I expect.


Python is my favorite language and I really liked Go as I read about it. When time came to actually learn and use it, I was... Disappointed.

Sticking with python still, for the time being.


Just use modern C++


Couldn't agree more, a much better investment of anyones time. C++ won't suddenly refuse to solve your problems because they don't fit into an arbitrarily limited view of the world. And some of the stuff coming out of standardization lately is simply awesome.


Can you share some of it. Trying to get better at C++ here.


Sure thing. Bear in mind that this is my way of doing it; plenty of people will yell blasphemy at the choices I make, and some may well turn out to be suboptimal without 32 years of experience to back them up.

https://github.com/andreas-gone-wild/snackis


I would, but package management for C & C++ is still in the same shape it was 25 years ago - nonexistent.


I haven't looked at Go yet, but all these "is so easy to learn" and "generics are bad because they're not easy to learn" articles on HN, I have to wonder if this language is really so great or people push it because of the politics of people making it.


To me, the language really is so great. I've discussed this with a friend, but in my 4.5 yrs of using it in production environments I've never found myself held back by the lack of generics. The apps I write need to be high availability, doing 1k req/sec on avg on one server, and go has never been the bottleneck.

I come from originally a PHP background, and for me to do a fraction of what Go can do would require me to go in and mess with php config files and spin up more servers in order to get the performance I need, and with Go that's just not the case.


Only one way to find out… learn some Go? :)

As author of this article, I can only say that I wrote about Go because I honestly like it, not because I have any agenda.


It will take all of 2 hours tops to go from zero to writing an interesting program.


While I do like that Go is ready to learn, I like that it is small enough to hold in my head. Pretty much everything works intuitively, save for a couple surprises. The same goes for its tooling. There is no complex project or package tooling to learn either.

That said, it doesn't have a passable story for sum types or generics, which are important for the kind of programs I write these days. I'm convinced that summertime could build something as simple as Go, but with better abstraction facilities. Ideally this language would look like Rust and compile to Go.


> There is no complex project or package tooling to learn either.

Question, how do you handle dependencies without them ending up checked in in your git? I’ve had no success yet with go and dependencies, there’s no simple way like in the Java world to just define a list of dependencies and have the built tool automatically fetch them in some dotfolder, and take care of the rest, is there?


Use dep, which they're planning to add to the official tools like 'go get'. Then add your vendor directory to your gitignore, and you're done.


I don’t want a vendor directory in the first place, how do I avoid that? I want it to just automatically do its stuff just like maven/gradle/sbt work, and not deal with any damn dependencies. I want it to automatically set the dependency path, and handle incremental compiles.

If people claim it has so much better tooling than Java, then I expect at least it to work as well as Java’s tooling.


You're confused, Java's tooling is more complex/less intuitive. It doesn't matter where the dependency data lives on your system; it's completely transparent to you.


> It doesn't matter where the dependency data lives on your system; it's completely transparent to you.

Until some idiot checks it in on git despite the .gitignore (yes, this is possible, as I discovered after people accidentally did it).

Java’s tooling is far more intuitive. I don’t have to configure a GOPATH, or deal with go get or deps or stuff, I simply define my build.gradle.kts, do gradle build, and I’m done. I don’t have to care where dependencies are, or what transpilation steps are happening.

If I want to add a preprocessor, I import it the same way that I’d import a normal dependency, just with another directive – `compile 'com.jakewharton:butterknife:8.8.1'` vs `annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'`.

This is something I really miss in the JS and Go and C and C++ world. It all just works.


> Until some idiot checks it in on git despite the .gitignore (yes, this is possible, as I discovered after people accidentally did it).

This seems like a ridiculous edge case to optimize for. It's rare and trivially corrected.

> Java’s tooling is far more intuitive. I don’t have to configure a GOPATH, or deal with go get or deps or stuff, I simply define my build.gradle.kts, do gradle build, and I’m done. I don’t have to care where dependencies are, or what transpilation steps are happening.

You don't have to configure a $GOPATH in Go. If you don't specify it, it defaults to $HOME/go. Just use `dep` to manage your versioned dependencies or `go get` if you're prototyping. Unlike Gradle, there is no scripting language to learn--static binaries and native dependencies are supported with no extra configuration, and everything is fast without a complicated daemon to install.


I'm trying to understand your complaint.

Obviously you'll need a vendor directory somewhere containing the source code of your dependencies. Maven places them outside the project's root dir (defaults to ~/.m2/repository), whereas Go puts them inside the project's root dir. Tomato-tomato. They have to exist on your system somewhere.


> They have to exist on your system somewhere.

Yes, but they shouldn’t be something I’d have to ever care about. Whenever I type "build", the build tool should automatically manage the dependencies and invoke the build process.


What politics?


Its the best, but I'm sad and shamed it is owned by google.


Why are you sad? It is backed up by on the biggest Software companies in the world and the amount of free stuff Google is throwing around is mind boggling.


It is backed up by on the biggest Software companies in the world and the amount of stuff Google has their hands in is mind boggling.


I love Go! It houses us and puts food in our mouths. It also powers our side projects. Go is awesome!


I've heard the same "it pays the bills" argument quite often for PHP. ;)


It literally houses you and puts food in your mouth? I'd like to see that.


Maybe they* live inside the O? Confusing.


She =) But thanks for your sexist assumptions! They're awesome!


Did you just assume personhood? You might be responding to a Markov chain for all we know.


Are you saying Markov chains can't be sexist?


Seeing that they are mere algorithms, yes. Being X implies intention. At best they can accidentally put out something sexist as a result of their input.


That comment has got to be a joke... Right?


Sexist or just "statistically likely"?

And aren't assumptions the very thing one has to base on statistics?


To paraphrase Upton Sinclair: it is difficult to get someone to understand something, when their salary depends on their not understanding it.


Well, cocaine does that too for some families, so "houses us and puts food in our mouths" is hardly an argument.

Especially since one can pay the bills even easier with more popular languages (e.g. Javascript, Java, C#) with more job postings, so that's not a particular argument in favor of Go.




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: