News for hackers. Stuff that matters.
Re:Why Go and Not Rust? by pornel on Monday September 16, 2019 @10:21AM (#20984279)
Not disagreeing with the sentiment, but I dislike the word "simple" used to describe languages, because it has two meanings: simple = "consists of few parts" and simple = "easy to use", and these are not the same.

Certain things in Go are not easy (not simple), because Go has few language features (is simple).

Go has definitely a lower barrier to entry and is very productive for certain size and complexity of a project. However, as you start pushing beyond "scale" Go is designed for, Go becomes less simple to use. To appreciate things like generics, non-nullable types, no shared mutable state, you have to be working on a problem that requires these things, and only then these extra features pay off and make development and maintenance easier.

Re:Why Go and Not Rust? by kristoff_it on Monday September 16, 2019 @10:37AM (#20984473)
Whenever I used the word `simple` I did it not to mean easy. You raise a good point and I agree that simplicity != ease. I think it's a well known point of discussion from rob pike and, although less authoritative, it's also the focus of my first ever blog post [1] :)

That said, I wanted to talk about Go for enterprise development, and I did explicitly made the point that some abstractions are in my opinion detrimental to the reality of enterprise software, and I suspect generics might be one of them. It's a big topic and I honestly don't know the definitive answer, but I just wanted to point that out. I do agree that non-nullable types are good and a big hole in Go's repertoire.

[1] https://kristoff.it/blog/simple-not-just-easy/

Re:Why Go and Not Rust? by KirinDave on Monday September 16, 2019 @11:31AM (#20985054)
Have you gone back and read that post you linked recently?

It seems to me like the final section has a lot of bad things to say about the methodlogy of a go developer. Huge, bloated toolchains required to make progress. Code volume rather than appropriate abstraction. To me, your MS Word vs LaTeX graph sure seems like it's damning "easy" languages like Golang in favor of other languages with more powerful abstractions.

You also assert that Golang is easier to learn than other languages. I don't think you've really got a leg to stand on there. It's "easy" for folks doing service development because the arbitrary decisions made by Golang were made from the perspective of someone experienced at writing web services. If you already know C and Python a bit, Golang cherrypicks a lot of good stuff, but if you don't (or you're not writing a bunch of web services that essentially do nothing but punt to C frameworks and validate strings in request headers) then Go's going to struggle, and folks have pointed this out.

It's pretty surprising to me that you write about how Generics are the death of enterprise software when so much quite-usable software uses generics. Why do yo simply get to forget the existence of the huge body of Java work and instead assert it's bad? Android uses generics in many cases where appropriate and it's one of the better UI kids available these days.

Even the Actor methodology you're citing as part of Golang as good is actually a fairly sophisticated abstraction with lots of implications for the runtime and execution order. Why is that specific programming abstraction given a pass because of its benefits, but writing a generic linked list is going to be the death of your programming organization?

You also defend the structuring of many enterprise groups even as you suggest that they lack training, refuse to pay technical debt, and place unreasonable burdens on developers. You seem to have just accepted this and said Golang helps you be more complicit in this mode of operation that you also seem to suggest is somewhat bad. Why would we want to pander to a methodology that asks junior developers to proceed without training and places focus on process and hyper-specialized domain experts rather than clear communication, sound architecture and sustainable velocity?

I'm quite confused how you can hold both these opinions at the same time. It seems like they're contradictory.

Re:Why Go and Not Rust? by kristoff_it on Monday September 16, 2019 @01:15PM (#20986312)
> "easy" languages like Golang in favor of other languages with more powerful abstractions.

Go is easier to learn than C# (I'll omit Java in this comment as I have more experience with the former), but that doesn't make Go an "easy language". The name itself implies that mastery doesn't come immediately.

The powerful abstractions that you mention, including generics, are indeed good things, but pardon me but I suspect you've never seen how badly and easily they can be abused in certain environments. You've probably seen the Factory<Factory<NaturalNumbersFacade>> joke somewhere, real live enterprise software is sometime like this, but unironically.

> Generics are the death of enterprise software

That's an hyperbole, I've never made such strong statement.

>Even the Actor methodology you're citing as part of Golang as good is actually a fairly sophisticated abstraction with lots of implications for the runtime and execution order. Why is that specific programming abstraction given a pass because of its benefits, but writing a generic linked list is going to be the death of your programming organization?

Goroutines and channels are simpler than the threaded multiplexing that C# does with its stackless coroutines. My argument is mainly related to the many ways you can mess up async/await in C# vs the 2-3 ways you can deadlock in Go. I link to a talk, an image and a blog post related to the subject.

> You also defend the structuring of many enterprise groups even as you suggest that they lack training, refuse to pay technical debt, and place unreasonable burdens on developers.

I don't defend nor encourage this, but that's what happens in real life. It's the result of many factors at play, some of which I described in the post, some of which even I don't understand. If I did, I would be way more rich :)

You can refute my assessment of reality, but "being complicit" is not exactly appropriate when 80% of the enterprise consultancy jobs out there are like this.

> Why would we want to pander to a methodology that asks junior developers to proceed without training and places focus on process and hyper-specialized domain experts rather than clear communication, sound architecture and sustainable velocity?

You can't change how things work until you understand why the work the way they do (or at least you can't reliably change the world unless you do). Refusing the current state of things is step 0 of N, and I've learned in my experience that change in big systems comes incrementally, you can't "distrupt all the things", so Go is (in my opinion) a step in the right direction.

I would recommend you talk with somebody you know that has this type of work experience, they will be able to convey to you how these things work better than I can, probably.

Re:Why Go and Not Rust? by PyroLagus on Monday September 16, 2019 @01:34PM (#20986543)
> The powerful abstractions that you mention, including generics, are indeed good things, but pardon me but I suspect you've never seen how badly and easily they can be abused in certain environments. You've probably seen the Factory<Factory<NaturalNumbersFacade>> joke somewhere, real live enterprise software is sometime like this, but unironically.

Isn't that more of a criticism of enterprise software than generics? If they can write ugly generic code, they sure as hell can write ugly Go code as well. They're just different different programming styles, and while some like one others prefer the other. Even when you code in ASM, you'll probably end up writing generic code down the line. You'll just be managing it manually rather than have a compiler, preprocessor, or templating engine do it for you. It's a preference, and I say to each their own. Also, the whole moralizing holier-than-thou simplicity and anti-abstraction talk is getting kind of annoying, but then again, there's lots of moralizing people in the Rust camp who are just as annoying.

Re:Why Go and Not Rust? by kristoff_it on Monday September 16, 2019 @01:40PM (#20986620)
> Isn't that more of a criticism of enterprise software than generics?

Absolutely yes! My whole argument is restricted to (how I experienced) enterprise development.

Re:Why Go and Not Rust? by KirinDave on Monday September 16, 2019 @01:46PM (#20986683)
Isn't this just post-hoc rationalization though?

People complain that Rustaceans are insistent to the point of being obnoxious about Rust. But I insist that Gophers turn post-hoc rationalization into an art form. Things are bad because Go didn't do them, if they were good Go would have.

Re:Why Go and Not Rust? by ratww on Monday September 16, 2019 @06:30PM (#20989191)
> You've probably seen the Factory<Factory<NaturalNumbersFacade>> joke somewhere, real live enterprise software is sometime like this, but unironically.

I'm sorry, this is a terrible argument. That's definitely not a common usage of Generics.

The common enterprise OOP idiom that is mocked is NaturalNumbersFacadeFactoryFactory, which use no Generics at all, leading to a large number of classes.

Ironically, if one used generics to replace factories like you did in your example, you would be able to replace hundreds or thousands of Factory or FactoryFactory classes in an enterprise application with a single Factory<T> class. Of course, that would probably be pointless. There's a reason multiple factories exist in a program, even though there are ways to replace them with something simpler.

I get it that Go programmers don't want the language to be complex, but Generics themselves don't have to be complex. They solve a lot of problems in a simple way and are MUCH easier to use than ad-hoc generics made using interface{} + Reflection.

Re:Why Go and Not Rust? by sytringy05 on Monday September 16, 2019 @08:57PM (#20990130)
It definitely is common with generics, it happens all the time. Here's some production code I've worked on recently:

     new TypeReference<FooResponseCollectionResource<MemberUpdate>>(){})
I like generics, but I don't love this sort of thing and it's not even a mis-use of them
Re:Why Go and Not Rust? by pjmlp on Tuesday September 17, 2019 @02:56AM (#20992404)
Many languages do support type alias. In C# you would do

    using NiceType = TypeReference<FooResponseCollectionResource<MemberUpdate>>
    // ....
    new NiceType ()
Re:Why Go and Not Rust? by ratww on Tuesday September 17, 2019 @11:38AM (#20996484)
My point was that the commonly mocked VisitorObserverFacadeFactoryFactory Java idiom doesn't normally use generics at all.

Of course you can mix generics with terribly named classes and OOP patterns, but that's hardly a problem with generics themselves.

Re:Why Go and Not Rust? by je42 on Tuesday September 17, 2019 @12:39AM (#20991617)
what's the alternative ? using an "untyped" variable ?

but then you loose type checking and some people don't like to loose type checking...

Re:Why Go and Not Rust? by KptMarchewa on Tuesday September 17, 2019 @07:46AM (#20993842)
Do not use patterns that require you to write code like that.
Re:Why Go and Not Rust? by Thiez on Tuesday September 17, 2019 @12:22PM (#20997015)
You never have cases where you have a list of lists? Or do you introduce a pointless wrapper type for the inner lists to "hide" the generics?
Re:Why Go and Not Rust? by ratww on Tuesday September 17, 2019 @11:39AM (#20996516)
That's the answer for me.

The problem in those cases always the abuse of often obsolete OOP patterns and misnamed classes.

Re:Why Go and Not Rust? by KirinDave on Tuesday September 17, 2019 @11:01AM (#20995951)
Or use type aliases that are helpful.
Re:Why Go and Not Rust? by naikrovek on Monday September 16, 2019 @08:21PM (#20989900)
> I'm sorry, this is a terrible argument. That's definitely not a common usage of Generics.

It is very common indeed in the three large Enterprise Java houses I've worked in over the past 15 years. FizzBuzzEnterpriseEdition is the reality in all three of those places. Not only is it reality, it is requirement.

Re:Why Go and Not Rust? by ratww on Tuesday September 17, 2019 @11:30AM (#20996355)
FizzBuzzEnterpriseEdition doesn't use generic classes.

You're just making my point for me.

Re:Why Go and Not Rust? by KirinDave on Monday September 16, 2019 @01:45PM (#20986674)
> Go is easier to learn than C# (I'll omit Java in this comment as I have more experience with the former), but that doesn't make Go an "easy language". The name itself implies that mastery doesn't come immediately.

I'm using "easy" in the sense of "easy" vs "simple". I think that the modern "commonly in-use" parts of C# are about the same size as Golang, to my sense of scale.

> , but pardon me but I suspect you've never seen how badly and easily they can be abused in certain environments. You've probably seen the Factory<Factory<NaturalNumbersFacade>> joke somewhere, real live enterprise software is sometime like this, but unironically.

Pardon me if I think it's profoundly disingenuous for you to conflate factory patterns (which can exist in literally any type system and language) with Generics, and let me again positively beg for pardoning if I come across thinking you don't really understand the Golang argument for generics if this is your go-to example.

> That's an hyperbole, I've never made such strong statement.

Perhaps, but you have lumped generics in with a group of features and said, "The Go community regards as anti-patterns many abstractions regularly employed by Java / C#" and essentially intimdated that Generics are almost never good.

Further, your rhetoric carefully partitions everyone else's abstractions as risky anti-patterns while below you carefully rationalize Go's abstractions as in fact good. Your argument there essentially boils down to taste and fear.

> Goroutines and channels are simpler than the threaded multiplexing that C# does with its stackless coroutines. My argument is mainly related to the many ways you can mess up async/await in C# vs the 2-3 ways you can deadlock in Go. I link to a talk, an image and a blog post related to the subject.

No, they're not universally so. Firstly, actors and threads define equivalent systems [0], they simply have different tradeoffs within that space. There are some constructs where actors are easier (e.g., when a process maps well to an individual loop consuming a mailbox) and some where they simply are not (e.g., when spinning over shared memory and hoping to pull out a copy to another space). What's more, there's an awful lot of progress on the shared space model by attacking the memory coherency problem.

It's quite possible to build systems that are as resistant to deadlock as Golang using threaded models. They're also amenable to static analysis. There's also a very large and useful body of research on using structures that are unopinionated about the order that they receive updates in (CRDTs are a good place to start here), making the strict linearization of actors unnecessary and even a performance bottleneck sometimes.

You're either unaware of it, or you're uninterested. I don't know, but if it is the former then you should probably keep up with what's going on there.

> I don't defend nor encourage this, but that's what happens in real life. It's the result of many factors at play, some of which I described in the post, some of which even I don't understand. If I did, I would be way more rich :)

You are encouraging it though. You're saying we should use tools that are designed to accommodate it. That's literally baking this mode of operation into our automation at a fundamental level. And as you've implied, once there it often takes monumental effort to get it dislodged.

> You can't change how things work until you understand why the work the way they do

That's my line. The way it works is people suggesting that there is no other way it could work, and then baking these assumptions deeply into their corporate structure.

> I would recommend you talk with somebody you know that has this type of work experience, they will be able to convey to you how these things work better than I can, probably.

Hi. I'm Dave. I'm a SRM at Google right now but I've also been a Director for Capital One, worked in software at numerous companies including Microsoft and about a dozen startups in technical and advisory capacities, and founded (and sold) my own startup. I've been in management in one capacity or another for nearly a decade.

And a lot of my time spent when I'm not working directly on projects is advocating for developers to be more empowered, receive more training, and have the power to actually set and run a sustainable pace, even if that means a slow start to burn away the technical debt in place.

But thanks, I'll keep that in mind.

[0]: "On the Duality of Operating System Structures", by Lauer & Needham http://web.cecs.pdx.edu/~walpole/class/cs533/papers/duality7...

Re:Why Go and Not Rust? by jacquesm on Monday September 16, 2019 @02:40PM (#20987192)
> Your argument there essentially boils down to taste and fear.

I suspect the larger factor may simply be familiarity. It is very rare to see a balanced piece about some programming language - let alone one about two programming languages - where the author has an equal and substantial amount of experience with both and is really able to compare them on their merits.

Re:Why Go and Not Rust? by dsirola on Monday September 16, 2019 @05:16PM (#20988647)
You can mess up async/await in C# in exactly 0 ways. Calling .Result is just a bad practice and should never be done.
Re:Why Go and Not Rust? by naikrovek on Monday September 16, 2019 @08:26PM (#20989933)
Uhh, I've messed it up a lot more ways than zero, and it's easy to do. In fact, doing the exact same thing in a console app and a Windows Forms app will result in a deadlock in one of them, for absolutely no obvious reason.

Async and await in C# may be wonderful to some, but they are horribly broken to others.

Re:Why Go and Not Rust? by Const-me on Tuesday September 17, 2019 @02:22AM (#20992203)
I agree there're caveats, I experienced that too.

I disagree they're broken.

C# 7.1 introduced async main. No reason to call Task.Result in console programs.

Even before that feature arrived, visual studio debugger could resolve that literally in a minute. Press F5, reproduce deadlock, you'll see exactly what's locked and why.

Re:Why Go and Not Rust? by EvanCarroll on Monday September 16, 2019 @02:09PM (#20986920)
I also don't understand your argument on simplicity. You make mention in multiple points about "await". You don't like it. We get it. In what way is it not simple? And how does it follow that Go is more simple (using the same definition).
Re:Why Go and Not Rust? by kristoff_it on Monday September 16, 2019 @03:05PM (#20987439)
I actually quite like it. C# has a peculiar async runtime that when misused tends to deadlock, and that's the entirety of my issue with it... and the fact that async/await is a half baked monad in most languages, but I say that with love (mostly) :)
Re:Why Go and Not Rust? by minraws on Monday September 16, 2019 @11:41AM (#20985175)
I almost completely agree with everything in the article except the word "Enterprise", it might just be me but it can mean a lot of things to say it's good for enterprises.

We could say it's good for Web and Services Enterprises (probably) but for a different kind of an enterprise it can vary, depending on their business model and requirements. As the significance of it's features can change.

Tldr; All languages have a place(IMHO), Go is a simpler language with reasonable value in the current industry for various reasons.

Re:Why Go and Not Rust? by asdkhadsj on Monday September 16, 2019 @10:32AM (#20984410)
> Certain things in Go are not easy (not simple), because Go has few language features (is simple).

Too true, I touch on that in a post I made here as well. In Go I often found myself having to reuse logic in functions that, in Rust, could be hidden behind iterators or custom iterator implementations.

While the Rust version is definitely more complex if you look at the implementation of the iterator; in practice you are just using the iterator - and that ends up meaning the problem you're solving keeps locality, and is easier to reason about. In my experience, at least.

Re:Why Go and Not Rust? by PyroLagus on Monday September 16, 2019 @02:00PM (#20986821)
I wonder if it is actually more complex. Emergent complexity is a thing, and one only needs to look at Go (the game; pun definitely (not) intended). The rules are dead-simple; you can learn them in under a minute. But to actually play the game well, you have to learn a lot more. You have to memorize openings, learn to identify and utilize patterns, etc. There is a lot of "meta-play" going on, and you could say that high-level Go play is full of abstractions. In fact, you won't have a chance without the abstractions. If you only see individual stones rather than shapes, you're done for. I think the same applies to languages like Go. You don't have generics, but if you want to effectively re-use code, you need abstractions. The difference now is that in languages like Rust, you have predefined and marked abstractions, while in Go, you define them yourself and need to recognize them yourself. Granted, Go also makes certain kinds of abstractions difficult or impossible to manually define within the language, so you may end up with copy-pasted code, but I imagine even that will be manually abstracted through naming and such.

The Rust iterator is a pretty simple abstraction in my opinion. It's essentially a lazy list. You see an iterator used, you know what you're getting. You see the map function used, you know it's the same as a for loop over all the elements. A fold/reduce is just a for loop over all elements with a result variable that gets returned. I really don't think using iterators is any more complex than a for loop, and with a for loop, you actually have to look through it to identify the pattern used and find out what it does. I'd say having to manually check for patterns is more work, but I couldn't say which one is more complex; maybe neither is.

Re:Why Go and Not Rust? by kjksf on Monday September 16, 2019 @03:16PM (#20987563)
You can encapsulate iteration logic in Go.

I do it in my libraries when warranted.

The pattern is:

  v := NewIteratedValue()
  for v.Next() {
    item := v.Item
    // process item
  }
  if v.Err() != nil {
     // process error
  }
A variation of this pattern exists in standard library and third part libraries.

I know that you meant implementing some sort of iteration protocol natively supported by the language, so that you can write:

  for v { ... }
vs:

  for v.Next() { }
But you ended up making much stronger and untrue claim that one can't write re-usable iteration logic in Go.
Re:Why Go and Not Rust? by atombender on Monday September 16, 2019 @03:43PM (#20987837)
That's an apples-to-oranges comparison because your iterator interface here isn't generic like Rust's. It isn't reusable.

Your iterator has to be specific to a set of types — "v.Item" in your example is always of some specific type. Using an untyped interface{} would be worse than any alternative because every single use would have to use type switches and casting; you lose out of compile-type type safety.

Because of this, even if you have a local iteration system, it isn't composable beyond your package and its types. Given this (simpler) interface:

  type Iterator interface {
    Next() (Foo, error)
  }
...then I can write a map function:

  func Map(it Iterator, mapper func(Foo) Foo)) Iterator
...but I cannot write a generic one that works with anything other than Foo. And if I need this:

  func MapFooToBar(it Iterator, mapper func(Foo) Bar)) Iterator
...then I have to write it just for that purpose.

That's why there's no "iterator library" for Go, like there is with Rust.

Re:Why Go and Not Rust? by asdkhadsj on Tuesday September 17, 2019 @10:15AM (#20995326)
> But you ended up making much stronger and untrue claim that one can't write re-usable iteration logic in Go.

Not at all. Are you telling me that `v.Next()` can be written in a reusable way for different data structures? Nonsense.

`v.Next()` will have a single, bound return type. So at that point you're re-implementing iterators for anything you want to iterate on.

Furthermore, lets say I want to `v.Next().Map()`. How can I write a Map function in a reusable way? The entirety of your iterator chain would have to be custom implemented for the one data structure you're using. Or you throw your entire type information away and use `interface{}`.

With Go, your limit of reusability is hand writing the entire iterator implementation per type. Which is hardly reusable in my view. I touched on this when I mentioned creating separate functions for these patterns. That's all you're doing here - creating custom methods to make something look like, but not behave like an actual iterator. No Map support, no Filter, no .. anything. All you made was a loop, and a hand written one.

I'm not trying to be overly negative here. However saying Go has an iterator pattern is imo strongly misleading.

Re:Why Go and Not Rust? by social_quotient on Monday September 16, 2019 @02:54PM (#20987334)
re: Simple So it took me a number of years running a tech agency to realize that the words "simple" and “easy” are bad. In my job I now correct my, and our project managers, from using the word "simple" to the word "straightforward". I find that the term simple connotes a feeling of the task/work being easy and thereby quick to get done. As an agency the term “simple” speaks not only to risk and ease of completion but also budget, as a function of time.

Moving 10,000 bricks from point A to B is likely simple or easy, but it takes time. If not careful a client can think “oh it’s just moving 10K bricks 5 feet over, they should automagically be able to do this since John said it was “simple” ”. What I intended to impart was that I know how to do it, no solutioning needed, we have the skills and resources to get it done, and we can probably get moving on this quickly. Now I say something more like … “Moving 10,000 bricks from A to B is straightforward for my team, when do you want us to get started”.

Re:Why Go and Not Rust? by slifin on Monday September 16, 2019 @12:21PM (#20985667)
Rich Hickey describes simple as unbraided, like a class is identity, state and schema all braided together

And easy as close by and accessible i.e. npm i latest-framework might be easy but not simple

https://www.infoq.com/presentations/Simple-Made-Easy/

Re:Why Go and Not Rust? by modwest on Monday September 16, 2019 @04:57PM (#20988529)
This presentation had an outsize influence on my professional development as a programmer. If I've watched it once (and I have), I've watched it a dozen times.

edit: The "Limits" slide (go to 12:30 in the vid) is one that I really internalized early on. And looking at it again years later, the principles from that slide absolutely guide my app development:

- We can only hope to make reliable those things we can understand

- We can only consider a few things at a time

- Intertwined things must be considered together

- Complexity undermines understanding

Re:Why Go and Not Rust? by setr on Monday September 16, 2019 @12:36PM (#20985839)
isn't the same idea exactly covered by the term "(de)coupled"?
Re:Why Go and Not Rust? by modwest on Monday September 16, 2019 @04:40PM (#20988348)
It can include decoupling, but no it's not synonymous.
Re:Why Go and Not Rust? by mbillie1 on Monday September 16, 2019 @10:51AM (#20984625)
> However, as you start pushing beyond "scale" Go is designed for,

Go was designed at Google to be used internally at Google, so frankly it's hard to imagine commonly pushing past the "scale" Go was designed for.

Re:Why Go and Not Rust? by elsurudo on Monday September 16, 2019 @10:54AM (#20984657)
I assume the GP meant "scale of codebase complexity" – which is orthogonal to whether something is "web scale" (ie. everything Google does).
Re:Why Go and Not Rust? by creyes on Monday September 16, 2019 @11:02AM (#20984747)
Isn't the Google codebase infamously a monorepo with billions of loc? That seems like it fits "scale of codebase complexity" as well as "web scale"
Re:Why Go and Not Rust? by munificent on Monday September 16, 2019 @01:07PM (#20986185)
It's a monolithic repo, but not a monolithic codebase. It contains many many separate projects, libraries, and applications. There's a lot of code reuse, but it's not like you have to wrap your head around the whole thing.
Re:Why Go and Not Rust? by jcranmer on Monday September 16, 2019 @11:05AM (#20984784)
Yes, but much (if not most) of that codebase is in C++.
Re:Why Go and Not Rust? by jimbokun on Monday September 16, 2019 @07:08PM (#20989461)
How do you check out a project like that?
Re:Why Go and Not Rust? by bt848 on Monday September 16, 2019 @11:43AM (#20985189)
Go was designed for Google-scale and Google-style logs analysis, for which it has been very successful. The fact that it comes with a decent HTTP and RPC server is the inevitable consequence of the fact that every process at that company is expected to present HTTP and RPC control and diagnostic services in addition to its primary purpose.
Re:Why Go and Not Rust? by coldtea on Monday September 16, 2019 @12:07PM (#20985505)
>Go was designed at Google to be used internally at Google

That's not true, expect in a pedantic way. Google was "designed at Google to be used internally at Google" only in that:

(a) a few people at Google, on their own, designed a language (mostly based on an older Plan 9 language some had helped built) - not at the request of Google execs, nor as an explicit company-mandated project to create a language to solve Google's problems. It was almost on of these "20% spare time" things.

(b) these people added the features that they thought, as far as they were concerned that would be nice for programming Google style stuff. Those were based on their ad-hoc (and quite idiosyncratic) intuition and personal experience, and not some special research into programming at scale, or from involving the company at large at it.

Go was designed at Google, but not "from Google", if this makes sense. E.g. a few googler's building a language on their own initiative and among other work is not the same as Google, i.e. some higher-ups, saying "we need a language of our own that's a match for our developers' challenges" and the company devoting resources for this.

Google has 2 language projects they really put money on, Javascript as V8 and Dart. They built a top notch specialist team, spent lots of money for promotion and branding, built an IDE and developer tools for both, etc.

Apple has had Obj-C and now Swift like that, MS has C#, etc. Those are language projects with a big weight of the companies behind them.

Golang was not like that, but, according to all official accounts and recollections, a grassroots project, by a small team:

"Robert Griesemer, Rob Pike and Ken Thompson started sketching the goals for a new language on the white board on September 21, 2007. Within a few days the goals had settled into a plan to do something and a fair idea of what it would be. Design continued part-time in parallel with unrelated work. By January 2008, Ken had started work on a compiler with which to explore ideas; it generated C code as its output. By mid-year the language had become a full-time project and had settled enough to attempt a production compiler. In May 2008, Ian Taylor independently started on a GCC front end for Go using the draft specification. Russ Cox joined in late 2008 and helped move the language and libraries from prototype to reality."

It was never officially intended to be "Google's development language" or had a major push from Google. Since then, and after the first few years, Google seems to have devoted more money and time to Go, and several Google internal projects have adopted it, but Google is fine with C++, Java, and Python as well.

Re:Why Go and Not Rust? by skybrian on Monday September 16, 2019 @03:08PM (#20987467)
It seems like you're setting up a false dichotomy. Researchers working at a company are often thinking about solving company problems, even if their particular solution doesn't have management support yet. Getting official approval often involves advocates selling their particular solution to management.

In particular, language designers typically have concrete problems in mind, even if they're inventing a general-purpose language. It's enough to say that Go's designers expected to use their new language at Google, so it needed to work well in Google's environment and solve some problems that weren't currently being solved well in that environment. If it didn't work at Google, then they wouldn't have succeeded at their original goal.

While it's not the most popular language at Google, Go is officially supported for server-side projects (communicating via RPC with many other internal servers), and has been for some time. That's a high bar that few languages meet, and about as official as it gets. If it didn't succeed internally then the Go team probably wouldn't have had consistent management support and stable funding over many years.

The other languages you mention (Dart and JavaScript) are considered client-side only within Google so they mostly don't compete with Go. For example, Node is supported for developer tools and external users, not because Google runs its own servers using Node. (Or at least that was true when I left.)

Re:Why Go and Not Rust? by cmrdporcupine on Monday September 16, 2019 @03:17PM (#20987570)
I don't think it's a false dichotomy. I don't think the teams that originally worked on the development of the Go language were Google production engineers of any sort.

I've been working at Google for 8 years and have yet to touch a Go codebase in production.

It's just not used that frequently.

Re:Why Go and Not Rust? by skybrian on Monday September 16, 2019 @04:14PM (#20988120)
If we're sharing anecdotes, I didn't write any C++ in over a decade at Google.

But I'm not going to dispute that it's the most-used server-side language, because I've seen the statistics.

Re:Why Go and Not Rust? by coldtea on Monday September 16, 2019 @05:40PM (#20988847)
How about the statistics you've seen on Go?
Re:Why Go and Not Rust? by skybrian on Monday September 16, 2019 @08:02PM (#20989789)
I don't remember (other than being up and to the right) and it seems not to be published.
Re:Why Go and Not Rust? by coldtea on Monday September 16, 2019 @05:36PM (#20988811)
>Researchers working at a company are often thinking about solving company problems, even if their particular solution doesn't have management support yet

Yes.

But it's another thing to have a company's the management, say "we want a team to create a language to solve programming at our scale" and throw full resources and money at it (at C#/Java/V8/Swift scale) and have it adopted by mandate for further development,

(as is often implied),

and another thing to have an independent group of a few devs at a company to sit on their own, and say "you know what would be interesting to try to build? A language to handle what we see as Google scale problems", and then getting some more resources, and seeing some at the company adopting it, as just one more language used along with several other company-approved languages for greenfield stuff...

Re:Why Go and Not Rust? by skybrian on Monday September 16, 2019 @08:20PM (#20989897)
Uh, Google is unlikely to standardize on a single language. The codebase is too big, the incumbent languages are too well entrenched, and they've heavily invested in supporting multiple languages. I'm not sure anyone claimed that either?

If anything the trend is towards slowly adding acceptable languages, but the bar is pretty high.

Re:Why Go and Not Rust? by staticassertion on Monday September 16, 2019 @05:49PM (#20988912)
It's not that hard to imagine. Dropbox has talked about using Rust over Go for storage because cpu/memory efficiency was considerably better (4x if I recall) in Rust.
Re:Why Go and Not Rust? by whateveracct on Monday September 16, 2019 @11:24AM (#20984981)
Go is pretty explicitly designed (as in there are quotes from the designers) with a low ceiling because Google doesn't want to trust their engineers to have nuanced programming taste.
Re:Why Go and Not Rust? by s17n on Monday September 16, 2019 @01:41PM (#20986623)
This is why Go is good. If you care about writing beautiful code, Go might not be for you. If you care about getting shit done, it’s a great language.
Re:Why Go and Not Rust? by whateveracct on Monday September 16, 2019 @02:40PM (#20987195)
Go is good at getting things done..until it isn't and you bump your head on the ceiling.

I know Go and Haskell equally well, and I get just as much shit done in Haskell and don't have to be a copy-paste machine sometimes. There are many benefits of Haskell and like-minded languages besides being "beautiful."

Feels like if the Go designers had the sense to include parametric polymorphism and sums (aka proven features from the 70's whose main "downside" is being weird to Go's target audience), it would be a great middleground.

Re:Why Go and Not Rust? by klodolph on Monday September 16, 2019 @03:52PM (#20987911)
Eh, in practice I haven’t missed explicit (closed) sum times as much as I thought I would. I started using Haskell many years ago (20-ish?) and have written some medium-size apps with it, and I’m very comfortable with using "switch x := y.(type)" in Go where I would use an ordinary "case y of" in Haskell. The only thing missing here is a compile-time check for completeness.

Missing polymorphism is a valid complaint but it hasn’t had the impact I thought it would.

Meanwhile, some of the programs I had written in Haskell I’ve rewritten in Go, e.g. due to problems with the use of finalizers (causing crashes!) in Haskell. You can chalk this up to poor library design but it simply isn’t a problem in Golang, which seems to avoid the finalizers more than other languages.

I’m going to continue using both Go and Haskell, I’m happy with both.

Re:Why Go and Not Rust? by whateveracct on Monday September 16, 2019 @04:40PM (#20988347)
Emulating sums with interfaces isn't the worst but proper sums with exhaustive checking make it way easier for the consumers of your code to also perform matches in a maintainable way. When I emulate sums, I keep the matching internal and at best I expose a function that is the equivalent of an exhaustive match (which takes a function per case)

I've never run into finalizer issues (or finalizers at all really) in Haskell but I'm sure they exist. What libraries in particular used finalizers that you had issues with? In general though I find resource management much easier in Haskell thanks to bracket, ResourceT, and the (imo very good!) exception handling stuff. Async exceptions in particular are a surprisingly nice feature when combined with threading!

The biggest place lack of parametric polymorphism hurts is in concurrency. I have to hand-roll so much concurrency in Go and I don't really have a good option for abstracting over various patterns.

> I'm going to continue using both Go and Haskell, I'm happy with both.

Yeah same here. I'm glad to have them both in my toolkit.

Re:Why Go and Not Rust? by stjohnswarts on Monday September 16, 2019 @03:53PM (#20987926)
I'm not asking for specifics but do you use Haskell at work? Is it in academia? I have worked for several large and small corps and no one has used Haskell. Most use C++, a lot use Go, a few use some rust, but none of them were using Haskell. I met people who use Haskell in their spare time because of their love for CS things, but never in production code.
Re:Why Go and Not Rust? by whateveracct on Monday September 16, 2019 @04:35PM (#20988298)
Without specifics..I've been writing Haskell professionally & in production for several years now for multiple companies.

None were academia & most were commercial enterprises (that most people have heard of)

Re:Why Go and Not Rust? by johnisgood on Monday September 16, 2019 @06:43PM (#20989291)
Beautiful is subjective, I know, but I think you can write beautiful code in Go. I like its simplicity and explicitness. Those things make it beautiful to me.
Re:Why Go and Not Rust? by unionpivo on Monday September 16, 2019 @11:03AM (#20984766)
I think OP thinks about different scale.

It's not scale about number of users or data, it's complexity scale.

Last enterprise app i worked on had (provided) something like 10.000 different api calls (and yes mostly because of bad/wrong initial design decisions), and over 50k different possible queries that it could run against database. (my job was to "make database go faster")

Just running unit tests took longer than 6hrs (of course most unit test went out and connected to the database, because why not \s).

It all could be replaced with dozen or so 10k to 30k lines go projects each, that would be a lot easier to maintain and to scale out.

Re:Why Go and Not Rust? by CaptainJustin on Monday September 16, 2019 @10:59AM (#20984724)
People may also mean different things by scale.

For me, scale means more micro-services. For another person it means a bigger monolith.

Re:Why Go and Not Rust? by erk__ on Monday September 16, 2019 @11:01AM (#20984739)
Which is probably the reason Google have made tools like a decorator to transform code with generics to valid go code.
Re:Why Go and Not Rust? by melling on Monday September 16, 2019 @01:04PM (#20986147)
“non-nullable types“

This is not some advanced feature. I would think this should be the default in any language.

Re:Why Go and Not Rust? by crimsonalucard on Monday September 16, 2019 @01:06PM (#20986177)
All the popular languages from last gen, did not have non-nullable types.
Re:Why Go and Not Rust? by jerf on Monday September 16, 2019 @03:01PM (#20987402)
We're accustomed to thinking of our world as really fast moving with constant technology turnover, but computer programming languages turn over at maybe twice the speed of human generations. A lot of the features that HN posters, including me, simply can't imagine a language without have yet to penetrate the top ten list of current programming languages at all.

My point isn't that this is wrong, but just to suggest that people's mental models incorporate the idea that programming languages actually move pretty slowly. There's a constant froth of undergrowth in the forest, but it takes a long time to establish a tree, and a long time for it to be supplanted by another.

Re:Why Go and Not Rust? by TheCoelacanth on Monday September 16, 2019 @03:54PM (#20987931)
And it was a mistake in all of them.
Re:Why Go and Not Rust? by crimsonalucard on Monday September 16, 2019 @04:21PM (#20988177)
"I call it my billion-dollar mistake…At that time, I was designing the first comprehensive type system for references in an object-oriented language. My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years." – Tony Hoare, inventor of ALGOL W.
Re:Why Go and Not Rust? by littlestymaar on Monday September 16, 2019 @02:06PM (#20986880)
A good example of that is the difference of allocation handling in both languages: Go is simpler than Rust because in Go everything is automatic, while in Rust there is an explicit Box if you want to allocate on the heap. But avoiding heap allocation is easier in Rust than in Go because of the explicitness vs automatic management.
Re:Why Go and Not Rust? by takeda on Monday September 16, 2019 @01:13PM (#20986269)
Good point, actually C is perfect example of this, it is a actually quite simple language that is not that simple to use.
Re:Why Go and Not Rust? by larusso on Monday September 16, 2019 @10:45AM (#20984553)
Rich Hockey made a nice talk about this.

https://youtu.be/34_L7t7fD_U

Re:Why Go and Not Rust? by munificent on Monday September 16, 2019 @01:06PM (#20986169)
Auto-complete turning his name into "Rick Hockey" does actually explain what's been going on with Rich's hair over the past few years.
Re:Why Go and Not Rust? by larusso on Wednesday September 18, 2019 @01:04PM (#21007406)
How stupid of me not to spot this ...
Re:Why Go and Not Rust? by iwintermute on Monday September 16, 2019 @11:00AM (#20984736)
he also had another talk https://www.infoq.com/presentations/Design-Composition-Perfo...

and I would argue there's idea that simplicity of the instrument/tool is not a problem in itself and we shouldn't lose it in pursuit of 'ease'

Re:Why Go and Not Rust? by dunk010 on Monday September 16, 2019 @10:53AM (#20984652)
Yup. This is the origin of this idea.
Re:Why Go and Not Rust? by ospider on Tuesday September 17, 2019 @10:38PM (#21001993)
Go can not be simple, because software itself is a complex beast, language really does not matter.

One thing that gophers say a lot is the count of Go's keywords is minimal. This is true literally, only 25 keywords as of Go 1.13. But it does not reduce the complexity of writing code, it just hides them.

For example, Go does not have the `new` keyword, but it has `make` function, which is so powerful that one of my friends actually thought `make` was a keyword of Go.

Re:Why Go and Not Rust? by MuffinFlavored on Monday September 16, 2019 @10:34AM (#20984426)
Can somebody post an example of when you would use generics to solve a problem in the real world, and how that would be implemented in Go instead?
Re:Why Go and Not Rust? by otikik on Tuesday September 17, 2019 @06:04AM (#20993366)
Non-nullable types in are implemented using a combination of (powerful) enumeration types and generics.

Enumeration types in rust can be the usual ones you find in other languages:

    enum UserStatus {
      Anonymous,
      Registered,
      Confirmed,
    }
But their variants are not limited to names, they can be other things[1]:

    enum UserStatus {
      Anonymous,
      Registered{ email: Email, date: Date }, // a struct
      Confirmed(date), // a tuple
    }
Enum types can also be made generic. For example the Date type could be a parameter in the example above:

    enum UserStatus<T> {
      Anonymous,
      Registered{ email: Email, date: T }, // a struct
      Confirmed(T), // a tuple
    }

Which brings us to the Option type[2] in rust. It is an Enum with a generic type attribute, defined like this:

    enum Option<T>  
    {  
        Some(T), // a tuple with a single item of type T 
        None,
    }  
In rust, when a function says it returns an `i32`, it will always return an `i32`. It never returns `i32 or null`.

If you want not return an `i32` sometimes, you must specify exactly what else it can be. It is often convenient to return an Option<i32> instead. Then it can return `Some(i32)` or `None`. The difference with the "implicit null" from before is that the compiler will force you to "deconstruct the option safely", in compile time. You will never get a "Null Pointer Exception" in run time because of this.

For me, this is huge, and one of the reasons I like Rust more than Go.

[1]: https://doc.rust-lang.org/rust-by-example/custom_types/enum.... [2]: https://doc.rust-lang.org/std/option/

Re:Why Go and Not Rust? by killbot5000 on Monday September 16, 2019 @10:47AM (#20984575)
The simplest example I can think of is: Map(slice, func)

You can can implement this generically in Go using interface{} types and runtime type checking, but then you have runtime type checking failures.

A java/c++-esque "generics" implementation would be able to type-check at compile time.

Re:Why Go and Not Rust? by ori_b on Monday September 16, 2019 @10:55AM (#20984668)
You can implement it in Go using loops, and it's not significantly slower or more error prone.
Re:Why Go and Not Rust? by hauleth on Monday September 16, 2019 @11:02AM (#20984759)
Unless you want to implement that on top of your custom structure, like, for example, b-tree. Then you either need to write N different implementations for each separate tree or you need to use `interface{}`.
Re:Why Go and Not Rust? by ori_b on Monday September 16, 2019 @11:07AM (#20984800)
Yes, custom containers are one place that generics are very useful.

Go has the most useful containers built in. Most code I write doesn't need custom containers, even in languages with templates (I write far more C++ and Java than Go) -- so I find that I don't miss them much when I spend time in Gopherspace.

Re:Why Go and Not Rust? by NoodleIncident on Monday September 16, 2019 @01:09PM (#20986222)
The most egregious missing container is "set", coming from Python (as many Go developers do). After debugging, reviewing, and writing at least 3 different local implementations of a set, I can't wait for generics so that it can be written once and then never looked at again.
Re:Why Go and Not Rust? by mappu on Monday September 16, 2019 @04:49PM (#20988457)
I'm slightly surprised you found three different set implementations - `map[T]struct{}` is the idiomatic one i see everywhere.

I suppose it's not sorted or concurrent-safe?

Re:Why Go and Not Rust? by NoodleIncident on Monday September 16, 2019 @05:58PM (#20988984)
I mean that people make their own per-file or per-package set implementation for their service. There's no point putting it in a common utility package even within the same company, because it's specific to the type of what they're storing.

`map[T]struct{}` is only a type, it's not an implementation. You still need a handful of methods, that might be named inconsistently in each implementation by different developers. I will be happy when I never have to think about this again

Re:Why Go and Not Rust? by masklinn on Tuesday September 17, 2019 @07:37AM (#20993788)
> I'm slightly surprised you found three different set implementations - `map[T]struct{}` is the idiomatic one i see everywhere.

Set storage is not really the concern here, it's the set-theoretic operations which make sets useful (generally speaking, there are cases where all you need is the set being a set e.g. deduplication).

So I wouldn't be surprised that GP found several different implementations of union, intersection, difference, symmetric difference, subset, superset, …

Re:Why Go and Not Rust? by crimsonalucard on Monday September 16, 2019 @01:10PM (#20986230)
Yeah but you can't implement it generically.

That means for every conceivable input type and output type combination you have to have a new MAP or REDUCE function to handle it.

All Modern languages except golang and elm only require one implementation of MAP that can handle all type combinations.

It's called parametric polymorphism.

Re:Why Go and Not Rust? by excursionist on Monday September 16, 2019 @04:24PM (#20988203)
Elm has parametric polymorphism.
Re:Why Go and Not Rust? by crimsonalucard on Monday September 16, 2019 @05:18PM (#20988669)
you're right. My mistake.
Re:Why Go and Not Rust? by vbezhenar on Monday September 16, 2019 @03:53PM (#20987918)
Java is one example of modern language without proper generics. They have syntax sugar for Object references, but you can do almost the same with golang using interface{}.
Re:Why Go and Not Rust? by excursionist on Monday September 16, 2019 @04:26PM (#20988226)
I'm not sure what you mean by 'proper generics', but Java does have compile-time generics, ie List<T>, <A, B> B foo(A bar), etc.
Re:Why Go and Not Rust? by vbezhenar on Monday September 16, 2019 @06:00PM (#20988992)
Proper generics would allow you to parameterize with all types including primitive ones, not just Objects. Check out java.util.Arrays class as an example of why Java's generics are not proper: https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.h...
Re:Why Go and Not Rust? by leshow on Monday September 16, 2019 @07:03PM (#20989438)
You've got a kind of made up definition of 'proper'. Java has generics, they don't have the best implementation of it I've seen, but I wouldn't call it 'improper'. It's just not a word that has any specific meaning in this context.

I seem to remember an article being written a while ago that found Java's type system, with the addition of generics, was unsound. Maybe that's what you're trying to say.

Re:Why Go and Not Rust? by vbezhenar on Tuesday September 17, 2019 @07:36AM (#20993781)
Java generics is a syntax sugar. They don't add anything substantial. You can use Object (or another bound type) everywhere you're using generic type. You only need to add few explicit casts, which are added by compiler anyway.

You can do exactly the same thing in Golang. Just use interface{} everywhere and add few casts where needed. That is Java generics.

Re:Why Go and Not Rust? by excursionist on Tuesday September 17, 2019 @09:55AM (#20995090)
> Java generics is a syntax sugar.

That's not true, Java generics are not just syntactic sugar.

> They don't add anything substantial.

They add parametric polymorphism and type safety.

> You can use Object (or another bound type) everywhere you're using generic type.

Only if you go out of your way to do so, and ignore warnings. This has less to do with how generics work in Java and more to do with the fact that Object can be explicitly cast to another type and vice versa.

> You can do exactly the same thing in Golang. Just use interface{} everywhere and add few casts where needed.

No, it's completely different.

Re:Why Go and Not Rust? by ori_b on Monday September 16, 2019 @03:46PM (#20987858)
Yes, I know what it's called. I have implemented generics in compilers. I still don't miss them in most go code, in practice.
Re:Why Go and Not Rust? by DocSavage on Monday September 16, 2019 @11:22AM (#20984953)
One example is n-dimensional arrays where each element could be a byte, uint16, int16, ... , uint64, int64, float, or even some custom vector. In a language with generics, you could describe the nD array more simply and the operators work depending on what was passed. The implementation can also be shared across a number of similar element types. In Go, though, you’d need to use interfaces and at some point you’d have to make tradeoffs about speed, simplicity of the implementation (e.g. hand-coding each element implementation) vs use of interface function calls to get properties, etc.

One example is to look at how Go handles the Image package vs other languages with generics. https://golang.org/pkg/image/

Re:Why Go and Not Rust? by mamcx on Monday September 16, 2019 @11:09AM (#20984828)
In fact with Go is even more obvious. Go don't have inheritance!

Traits is a way to solve it. But the problem is that in Go types are "too open". If you wanna constrain it more traits is not an elegant solution.

Generics is better in this case.

BTW: This is how is in Rust. Rust have traits but you fill the rest with generics.

I made a mini-go database command liner that I call from rust (so I get access to drivers that are not yet available in rust). Is much more boilerplate from some stuff that in the rust side is just Value<T>.

And type errors that Go have that rust don't.

I think that Rust & Go sharing some(most?) design principles (about how model types) make easier to see what each side make harder...

Re:Why Go and Not Rust? by jerf on Monday September 16, 2019 @03:04PM (#20987430)
You can prevent external packages from implementing your interfaces by adding unexported method names to your interface. Usually I'd call it an anti-pattern for interfaces, but I've done it a couple of times when there was literally no conceivable way for an external package to implement something conforming to a particular interface for various technical reasons.
Re:Why Go and Not Rust? by zenhack on Monday September 16, 2019 @05:20PM (#20988686)
Yeah, most "good" uses of this technique are kindof abusing it to substitue for some other feature the language doesn't have, the most common of which I can think of is combining it with type switches to get a poor-man's sum types (what rust calls enums). You see this a lot in code working with ASTs, especially.
Re:Why Go and Not Rust? by nine_k on Monday September 16, 2019 @10:41AM (#20984511)
You can solve any problem in a language without generics, such as Go, C, Fortran-IV, or any other Turing-complete language, including the Turing machine "assembly".

The difference is in speed of producing such code, amount of bugs introduced, ability to understand, modify, and evolve the code, etc.

Re:Why Go and Not Rust? by takeda on Monday September 16, 2019 @01:35PM (#20986558)
Don't know Fortran, but while C doesn't have generics you're getting similar behavior due to macros (for example min(), max() are macros) and weak typing. So the need of having generics there is much weaker.
Re:Why Go and Not Rust? by fwip on Monday September 16, 2019 @01:58PM (#20986797)
There are a number of tools (and the "go generate" construct) designed to support code generation. If you just want macro-level behavior, that's easy to do.
Re:Why Go and Not Rust? by takeda on Monday September 16, 2019 @02:48PM (#20987280)
Yes, and that's what I'm currently doing, but it is essentially just automating writing the same code multiple times. It still has issues, like having to remember to regenerate the code on change, or making harder to use IDE features to refactor. There are also some limitations it has.
Re:Why Go and Not Rust? by nine_k on Monday September 16, 2019 @03:16PM (#20987554)
> automating writing the same code multiple times

What would you call a language that forces you to write / use a preprocessor to introduce higher-level features?

Low-level. More specifically, low-level for the domain where you're working. C is admittedly low-level because it had to be minimal even for 1970 and close to the metal. Other languages usually enjoy less drastic design constraints.

Re:Why Go and Not Rust? by pjmlp on Monday September 16, 2019 @05:05PM (#20988580)
Yep, that is why some were already using PL/I and Algol dialects almost 10 years before C came to be, alongside Fortran, Cobol and Lisp.
Re:Why Go and Not Rust? by pjmlp on Tuesday September 17, 2019 @03:03AM (#20992441)
Just like Borland C++ 2.0 for MS-DOS did, before templates were started to be designed.

I let you research when it was released.

Re:Why Go and Not Rust? by pjmlp on Tuesday September 17, 2019 @03:01AM (#20992432)
Even C does have generics now (_Generic) even if quite limited.
Re:Why Go and Not Rust? by takeda on Tuesday September 17, 2019 @01:06PM (#20997495)
Neat, I had no idea.
Re:Why Go and Not Rust? by tgv on Monday September 16, 2019 @04:30PM (#20988252)
I have functions that have to deal with hierarchical data objects, JSON like things. All collections are identically typed (although they have optional fields, different length arrays, etc.), but there is more than one type. In order to write simple code, I wanted to write one function that gets them from the database, one to update a single record, one to notify of changes, etc. So my top-level type to cover all of these collections is map[string]interface{}, which in TypeScript would be Map<string, any>.

Then I ran unit tests, and sometimes a weird error cropped up. Turns out I made an error in an append: instead of concatenating two arrays, I added the second array as the last element of the first. That was a time consuming bummer.

This problem could have been prevented by two approaches: copying every function for every type, or generics.

Go is a nice language, which makes some tasks easy to implement, almost fool proof, but it still lacks in other areas.

Re:Why Go and Not Rust? by peterbraden on Monday September 16, 2019 @11:00AM (#20984733)
For a Math.max function you would normally have generic comparables and implement on that.

Go makes you implement max and min in all your codebases.

Re:Why Go and Not Rust? by takeda on Monday September 16, 2019 @01:37PM (#20986589)
Same with float, if you for some reason need to use float32, tough luck. Makes you wonder why even have types that aren't supported by the standard lib.
Re:Why Go and Not Rust? by leshow on Monday September 16, 2019 @12:09PM (#20985524)
literally any data structure that stores different types similarly. hashmaps, linkedlists, vectors, binary trees (assuming you can bound on some ordering function), etc, then all the operations you expect to work on those data structures. You could also define mapping operations that work on the containing structure and don't care much about the specific type of the contents. There's a million and one uses for generics (polymorphism).

In Go, I believe you need to give up type safety to write these implementations, by using Interface{}

Re:Why Go and Not Rust? by rmilejczz on Monday September 16, 2019 @11:20AM (#20984935)
A lot of the time you’ll end up with an implementation for each discrete possibility, but that’s pretty crappy especially if you have more than 3 or 4 discrete types you need logic for (though not always bad, some go libs follow this pattern e.g. sort offers a method for each basic type). You could use the empty interface (which is essentially ‘any’), but that generally requires you to do casting or runtime type checking and that’s suboptimal in a statically typed, compiled language.

Generally it makes more sense to describe an interface that can be satisfied by different types, and writing logic to handle that interface instead. Go may not have traditional generics but the interface pattern is certainly a kind of generic programming that can be used to achieve some powerful results. Because structs can satisfy many interfaces and interfaces can be satisfied with any kind of struct (if you want an in language example check out the io.Writer interface and the many functions that use it) you can end up with highly reusable code despite not having traditional generics.

Re:Why Go and Not Rust? by atoav on Monday September 16, 2019 @12:48PM (#20985962)
In my experience Generics become much more useful, when your typesystem is strict. I use them quite often in Rust, especially when writing functions that should take many different types as inputs/outputs.

You can get away without them in many cases, but if you are working on stuff that you want to reuse, generics are the way to go. In combination with Rust’s traits this is especially cool.

Re:Why Go and Not Rust? by zenhack on Monday September 16, 2019 @05:29PM (#20988748)
Re:Why Go and Not Rust? by walkingolof on Monday September 16, 2019 @10:31AM (#20984392)
>However, as you start pushing beyond "scale" Go is designed for, Go becomes less simple to use.

I wonder if that is really true, some really complex systems are written in Go and it does seem to scale well with that. Take Kubernetes for example.

Re:Why Go and Not Rust? by asdkhadsj on Monday September 16, 2019 @10:33AM (#20984419)
I view it as a problem of scaling comprehension. Not scaling of performance.
Re:Why Go and Not Rust? by hauleth on Monday September 16, 2019 @11:01AM (#20984737)
Yes this is still true[1]

[1]: https://www.youtube.com/watch?v=4VNDjwzzKPo

Re:Why Go and Not Rust? by arhyth on Tuesday September 17, 2019 @09:18PM (#21001670)
kind of agree but also disagree. the runway for Go to go (pun unintended) from easy to difficult to use because of it consisting few parts is far longer than for a developer using a feature rich language to eventually shoot themselves in the foot. let me throw in another language in the mix to describe what i personally think is _almost_ the best tradeoff between this difficult and easy simplicity. Elixir. it has almost the same amount of keywords (as a proxy measure to API surface) as Go but on the other hand it also exposes metaprogramming and so, if you really want to, you can easily shoot yourself in the foot. but in both languages, as I said for Go, the runway for language usability to go from easy to difficult due to their limited features is very very long.
Re:Why Go and Not Rust? by mlindner on Monday September 16, 2019 @01:37PM (#20986583)
The tasks you do with any language are often not simple. And the simpler the language you use the more complex and harder the task gets. Assembly language is "simple" in the extreme but getting a task done in it is not trivial.
Re:Why Go and Not Rust? by lostjohnny on Monday September 16, 2019 @12:02PM (#20985446)
> However, as you start pushing beyond "scale" Go is designed for

Like Google scale?

That's what Go is designed for.

Re:Why Go and Not Rust? by pjmlp on Monday September 16, 2019 @01:36PM (#20986566)
Yes, that is why Google mostly uses Java and C++ instead.
Re:Why Go and Not Rust? by geodel on Monday September 16, 2019 @02:50PM (#20987297)
Or it may be because Java and C++ are much older so lot more code is written in those. And companies do not replace working code just because new language developed in house has few more features.
Re:Why Go and Not Rust? by pjmlp on Monday September 16, 2019 @03:10PM (#20987491)
Except that lots of new code also get written in those languages.

Google's major Go projects appear to be gVisor, Android GPGPU debugger, Fucshia's TCP/IP stack and volume management tools and the download server as it was done by the Go team.

https://commandcenter.blogspot.com/2012/06/less-is-exponenti...

Re:Why Go and Not Rust? by xxxpupugo on Monday September 16, 2019 @03:30PM (#20987708)
You forgot kubernetes
Re:Why Go and Not Rust? by pjmlp on Monday September 16, 2019 @04:06PM (#20988049)
Re:Why Go and Not Rust? by geodel on Monday September 16, 2019 @07:01PM (#20989422)
From description:

"In this talk we explore the devastating effects using object oriented antipatterns in go while building programs in a monorepo. ... Unknown to most, Kubernetes was originally written in Java. If you have ever looked at the source code, or vendored a library you probably have already noticed a fair amount of factory patterns and singletons littered throughout the code base. "

So basically writing Java in Go lead to clusterfuck codebase.

Re:Why Go and Not Rust? by smarterclayton on Monday September 16, 2019 @11:40PM (#20991189)
This is a joke talk (hyperbolic)

Most of the codebase problems in Kube are:

1. we depended on half the Go ecosystem at one point (docker, grpc, etcd, a few others) which is hard to do with dependencies in go (few standardized libraries)

2. performance of serialization mattered and JSON and protobuf were still raw at the time

I don't think Kubernetes is any worse than any other large (3M+ LOC), relatively young codebase I've seen on average.

Re:Why Go and Not Rust? by lostjohnny on Tuesday September 17, 2019 @05:00AM (#20993077)
That's why they created Go, to get rid of Java and C++ for things like download.google.com

They are not scalable for Google scale and are not maintainable at google scale.

That's why Google C++ guidelines basically disallow everything that is problematic in C++ and enforce a style guide to

> Avoid surprising or dangerous constructs. C++ has features that are more surprising or dangerous than one might think at a glance

> Avoid constructs that our average C++ programmer would find tricky or hard to maintain. C++ has features that may not be generally appropriate because of the complexity they introduce to the code

> Be mindful of our scale. With a codebase of 100+ million lines and thousands of engineers, some mistakes and simplifications for one engineer can become costly for many.

Re:Why Go and Not Rust? by pjmlp on Wednesday September 18, 2019 @02:05AM (#21002730)
Yeah, better tell that to the Android, ChromeOS, Fuchsia, Maps, Search and Flutter teams.
Re:Why Go and Not Rust? by lostjohnny on Wednesday September 18, 2019 @05:37AM (#21003610)
You are sidetracking the conversation with a troll attitude.

I was replying to

> However, as you start pushing beyond "scale" Go is designed for

Go is designed for Google scale, I don't know anybody pushing beyond Google scale right now.

Anyway, I'm a nice person, you'll find your answer below

Enjoy

----------------

most of those projects are legacy software

did you expect search to be written in a language invented 10 years in the future?

Go is slowly replacing C++ to write the tooling.

C++ is simply not scalable enough for day by day use, Linus knew that 15 years ago.

Even Firefox is replacing it for its engine, it must mean something.

It can be done in C++ doesn't mean it should anymore.

Java is there because it runs in ads systems, you don't replace your core product overnight, just like in some banks you still find Cobol.

Java is the new Cobol.

Fuchsia is written mainly in C and Dart.

You wanna write an Haiku style microkernel?

C++ is fine, it's just a few thousands line of code.

Wanna write millions lines of code in a maintainable way at Google scale?

You don't start the project in C++ today, unless you're a crazy person.

Even ES5 Javascript is more maintainable than C++.