Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I wish they would just freeze the language and not add anything. I like it the way it is. I feel like the general attitude of software developers is: if it isn’t changing and being updated it’s dying. I think we should start putting weight on stable unchanging software.


Let's be fair, they held out against a very vocal community for a very long time.

They used that time to carefully evaluate the utility and ethos compatibility of generics. And they're taking time thoughtfully implementing them.

This is what you want out of a language. Thoughtful design and responsiveness.


And I bet that if Go ever gets generics, they will look extremely similar to everything everyone has been telling them for years, even though they dismissed that feedback for years as silly.

The switch from parentheses to square brackets is just the first step toward that admission.


Something interesting happened when comparing the history of systems programming languages from the early 60s, throughout the 70 and 80's.

The resistance of C's design adopting anything that was already considered good practices in designing secure OSes outside Bell Labs, has a very familiar feeling.


It's amazing how we got here... Your comment immediately reminded me of Tony Hoare's Turing Award lecture (https://www.cs.fsu.edu/~engelen/courses/COP4610/hoare.pdf) which contains (among other fun/depressing gems to reflect on) a bit on the obvious-even-to-customers sanity of avoiding core dumps or worse due to a lack of bounds-checking.

"A consequence of this principle [of security] is that every occurrence of every subscript of every subscripted variable was on every occasion checked at run time against both the upper and the lower declared bounds of the array. Many years later we asked our customers whether they wished us to provide an option to switch off these checks in the interests of efficiency on production runs. Unanimously, they urged us not to -- they already knew how frequently subscript errors occur on production runs where failure to detect them could be disastrous. I note with fear and horror that even in 1980, language designers and users have not learned this lesson. In any respectable branch of engineering, failure to observe such elementary precautions would have long been against the law."


Yes, that is one of my favorite quotes. The key point is " would have long been against the law".

Until this kind of issue start suffering lawsuits, most companies won't change their behaviour.

Look at Microsoft, all the security speech, C++ Core Guidelines, improving .NET for low level programming, new founded Rust love, yet the Azure Sphere team decided to use C on what is supposed to be the Fort Knox of IoT security. A bit though story to buy. I imagine the Phonon layer has probably hardware memory tagging, but they aren't revealing what it does.


> everything everyone has been telling them for years,

Some generic obsessed people talking about generics is neither everything nor everyone.


This is a fair comment. Even the article we’re reading is basically the thought behind why square brackets is the best way to signify a generic. There’s mentions of parsers and that kind of design thought is important in a language.


The question would be how are they solving it differently after these many years. They are just following what every other language has done for the years. We agree on having that restraint is good, if they see it as not required.


> I feel like the general attitude of software developers is: if it isn’t changing and being updated it’s dying. I think we should start putting weight on stable unchanging software.

I agree with this.

However, the key is to stop once you've implemented the right set of features. Minimalism is about implementing the minimum necessary and no less. I firmly believe that generics are in the right set of features for a statically-typed programming language.

The problem is that Go has already implemented some features which clearly aren't in the right set of features--such as `go generate`--which already allow you to implement a crappy version of generics. So now you're starting to move toward the problem that C++ and (to a lesser extent) JavaScript have, which is that there are 5 different ways to do the same thing, which don't necessarily interoperate well with each other. If go were being implemented from scratch, it would be better to have generics and not `go generate`, but given the language already has `go generate`, there's certainly some downside to adding generics. It's not a simple choice.


The irony of go generate is that a similar approach was taken by C++ compilers back in the early days.

To give a proper example, Borland C++ 1.0 for MS-DOS had BIDS, so their own collections library with safe strings and vectors, as it happened with all major C++ vendors back in the day.

Well BIDS 1.0 used pre-processor tricks to generate the desired code, basically you would define the desired types and then include the data structure you cared about, and do this multiple times.

Eventually templates came into the picture and BIDS 2.0 shipped with a template version, based on the ongoing discussions at ISO.

We are talking about 1990 here.

As for the 5 different ways, that is the sin of the languages that start small as a counter movement without understanding that the others are complex not because it is fun to make them complex, rather because languages are products like anything else in software, and either they adapt to their customer base or they fade away.


The basic problem I see with Go is that its users are ignorant of how other languages have solved (or failed to solve) problems.

> As for the 5 different ways, that is the sin of the languages that start small as a counter movement without understanding that the others are complex not because it is fun to make them complex, rather because languages are products like anything else in software, and either they adapt to their customer base or they fade away.

Well, that's somewhat true, but there are two ways to adapt while avoiding the problem of having 5 slightly different and incompatible ways to do the same thing:

1. Pick a good set of language features up front and stick to them, devoting further development efforts to a strong standard library rather than language features. Example: Erlang.

2. Break reverse compatibility and remove things. Example: Python.


Agreed, although from the point of view of languages as software products, Erlang seems to be around just to support Elixir, and Python took an heavy bill by going that way.


"go generate" is an half assed macro feature that shouldn't even part of any modern language. Even C has better macro... And it has absolutely nothing to do with genericity, your argument is a fallacy.

If Go really wanted to be open, then Go designers should just have created a virtual machine and let everybody code their own language on top.

Go right now is just basically C with garbage collection. Only C developers love that, and Go designers are well aware that it is an hindrace to adoption in enterprise. The pressure to change seldom comes from the community at large, but Google itself and big corps using Go.


> "go generate" is an half assed macro feature that shouldn't even part of any modern language.

Agreed.

> And it has absolutely nothing to do with genericity, your argument is a fallacy.

In arguments against adding generics, it's been cited numerous times that you can achieve similar code reuse via macros. It's been a while since I looked at the awfulness of `go generate` so I'm not going to attempt to demonstrate the equivalency with that syntax, but here's how you'd achieve something similar to genericity with macros in C:

Instead of:

    T swap<T>(T* left, T* right) {
        T temp = left;
        *left = *right;
        *right = temp;
    }

    ...

    int a = 1, b = 2;
    char c = 'c', d = 'd';

    swap<int>(&a, &b);
    swap<char>(&c, &d);
You do:

    #declare_swap_function(T) T swap_ ## T(T* left, T* right) {\
        T temp = left;\
        *left = *right;\
        *right = temp;\
    }

    ...

    declare_swap_function(int);
    declare_swap_function(char);

    ...

    int a = 1, b = 2;
    char c = 'c', d = 'd';

    swap_int(&a, &b);
    swap_char(&c, &d);
So, macros do have something to do with genericity.

Macros are certainly a crappy way to achieve genericity, however, especially since the original reason go didn't include generics was to compile in a single pass, and adding a preprocessor adds another pass.

It's clear you were ignorant here. That's fine--I don't expect you to know everything. But I think it's reasonable to expect that if you don't know what someone is talking about, you approach the conversation with some humility and ask questions before accusing someone of a logical fallacy. Ignorance is fine, arrogance isn't.


> such as `go generate`--which already allow you to implement a crappy version of generics

The design document for "go generate" listed many motivating use cases, and not one of them was generics. The raison d'être for "go generate" is not to simulate generics. Some people just saw the character sequence "gener..." and made it about generics.


Meanwhile I will never use Go until it has generics.

I wonder if there is more of people like me or people like you...


To be fair I will probably not use it even if it has generics, at least not if I can avoid it. It will still have nulls, lack sum types, have messed up dependency management and so on. Though in times when I have to use (because it was not in my control), I would rather have them.


You summarised almost perfectly my gripes with Go. Thank you. Just to add one: any type has a "zero values" as a default value, and the compiler doesn't force you to initialize stuff. That single misfeature caused basically all of my grey hair, and I'm still young.


What do you like to use?


I'm not a stickler for any specific features: it's more about having a group of features that synergize with each other. So far I've not found a language that does this perfectly, but I've found a few that I think do better than Go:

1. Elixir: Pros: Erlang threading model is clearly the best I've come across, expressive syntax, strong data structures and algorithms in standard library. Cons: Slow for some things, anemic standard library for common problem domains, small community.

2. Python: Pros: Strong standard library for common problem domains, supplemented by a strong community set of libraries. Generally intuitive. Cons: Slow for some things, poor threading, inconsistencies in syntax, general dominance of configuration-oriented programming frameworks rather than libraries in the community, types are just not quite strong enough.

3. C#: Pros: strong type system, speed. Cons: dependency injection hell, MS walled garden.

I'd like to add Rust and/or OCaml, to this list, but I don't know either well enough to be confident.


>MS walled garden

.NET Core is FOSS though?


On paper, but it sure doesn't feel like it when trying to use it.

It's nearly impossible to find out which of the umpteen repositories contains the source for the class you're trying to understand, and MSDN won't be of much help. Much of the standard library also has a bunch of decoy source files that only contain signatures and/or mocks, so it's a pain to find the real version.

OmniSharp has a "go-to-source" option, but you only get the real source if it's in the same solution. Otherwise you only get signatures. Try giving Metals[0] or Rust-Analyzer[1] a shot, this stuff is night-and-day.

The official debugger (vsdbg) only works in VS and VSCode (and explicitly not in FOSS builds of VSCode). There is netcoredbg[2], but I still haven't figured out how to convince Emacs to use it. This wouldn't be as much of a problem if the culture wasn't so hostile to printf debugging (for example, ~nobody bothers to implement helpful ToStrings).

There is a heavy cultural bias towards MS libraries, regardless of their merits (ASP.Net Core, DI hell, EFCore, etc). See [3] for an.. interesting example.

OmniSharp has a habit of giving up randomly, giving useless error messages, and most GH issues consist of people repeating "+1", until there is a one-liner about how an update fixed it. Root cause analysis, what's that?

[0]: https://scalameta.org/metals/

[1]: https://rust-analyzer.github.io/

[2]: https://github.com/Samsung/netcoredbg

[3]: https://old.reddit.com/r/csharp/comments/9kha39/does_anybody...


> It's nearly impossible to find out which of the umpteen repositories contains the source for the class you're trying to understand > OmniSharp has a "go-to-source" option, but you only get the real source if it's in the same solution.

I have to admit I almost never run into this issue because because I don't really care what the source of the standard library does, the docs have always been sufficient for me. You could try https://source.dot.net/ though.

In the very rare case I do want to see the source of some 3rd party code I use dnSpy. It isn't as nicely integrated, but it's a very nice decompiler and debugger.


Hm, I didn't realize .NET Core had been changed to an MIT license. That wasn't the case when I was working in C# on a regular basis.

My guess is that MS proprietary tooling still sucks out the air from FOSS tools, but I can't speak from experience there so I'll just admit I don't know how the ecosystem has changed since I worked in it.


Visual Studio is definitely still the ideal environment for writing C#, but JetBrains Rider is a solid alternative, and VS Code with the right set of extensions is probably "good enough" for most things.


Rust is my favourite. I wish I could try Haskell, Ocaml or Erlang professionally sometime. I was OK with Scala, and would like to check Kotlin too.


Visual Basic, strict mode.


A language can't be everything to everyone. Given its age it is very widely used. So I'm not sure the lack of genetics is really hurting adoption. You run the risk of driving away existing users but not attracting people that already wrote the language off.

I say this as someone that doesn't use it for similar reasons as you. But I have ran into the above trap before.


I don't know, in any production system without generics, the code just looks amateurish...


The thing is, for people who want generics, sum types, non-nullability etc, there are plenty of other languages to choose from. For those who specifically want a simple language, Go is (was?) one of very few options.


sum types and non-nullability are not complex.


Sure they are. Sum types usually mean a pattern matching syntax, destructuring, and a different declaration syntax. Rust’s match keyword, for example, is a powerful construct covering guards, destructuring, and different types of binding. Non-nullability requires generics for a result type which is a huge source of complexity. Generics impact parsing, code gen and runtime efficiency.


1) Non nullability can be implemented in language without generics, and for all types instead of just pointer types. That can be used to enforce null checking with pattern like:

    if let var_name = nullable_var { 
        // use var_name as non nullable
    } else {
        // nullable_var in null, handle null case
    }
And any tagged union can be reduced to nullable of member type without pattern matching, with some specific syntax. It is not hard with an imperative language.

2) Without generics, you are probably reinventing the same code, or using reflection which is not even type safe, or worse, using code generation. For instance D has generics AND good compile times. I guess Nim compiles fairly well too. Or you can choose partially type erasure based generics with a different tradeoff. There is no point in not having useful generic functions on generic data structures in a language that came in 2000s.

Once write Python or ruby or something and come back to Go. People without knowledge of other languages with generics tend to think you are writing for loop in while loop in if - else break monstrosity because native compilation and performance come with a cost in expressiveness, while it need not be.


There is nothing wrong with code generation, what do you mean by "or worse"?


Off the top of my head: Poor error messages, any type checking is run on the generated code so harder to enforce properties, and if code generation is not in-language, then the base logic can diverge for different types, which is bad when you find bugs.


>Non-nullability requires generics for a result type which is a huge source of complexity. Generics impact parsing, code gen and runtime efficiency.

The C# 8.0 approach to non-nullability doesn't require generics at all (though C# already has a robust generic system). They just made reference types work the same as value types, add a ? if you want it nullable, otherwise it isn't.

I think Rust's way of doing it with Option is probably a better way, but C#'s way of doing it is definitely more accessible to the average programmer.


You could have a very simple `match` with no nested patterns or guards, like Haskell's core language.

> Non-nullability requires generics for a result type which is a huge source of complexity.

Option could be another built-in generic like Map in Go. Or one could simply have to write a new Option type ever time. Sucks, but aren't go programmers used to this sort of thing?

> Generics impacts runtime efficiency.

False


However go’s switch statement already acts like pattern matching and destructiving in order to support interfaces.


Given the Polls of go programmers have consistently shown that the lack of generics is a problem.


Where do I participate in those polls? I'd like to put my voice against.


As we all know, the only true value a programming language has is whether or not a majority of programmers align with its ethos.


Based on the popularity of the language alone, I can say rather definitely the latter.


I'm sure that being backed by the largest software/advertising company in the world has nothing to do with its adoption rate, and that popularity is a direct mapping of quality of a programming language.


The Google backing and hype kept me away from Go for years. After being stuck with a succession of scripting languages that weren't doing it for me and being frustrated at the time it takes to be as productive in something like c, Go is really the sweet spot of readability, reliability and productivity for me. I think the Google backing may not be as advantageous as some people think. Dart did not become a popular language and would probably have died out if Flutter hadn't come along.


Yeah, Go being from Google is not necessarily a good thing. It means the language is under the control of a single company and, what's more, a company that is well-known for giving up on many of its projects.


And the open-source aspect of Go's development is managed entirely in Google services (the dev mailing list is a Google Group, you can't contribute without a Gmail address...the list is long). Sure it's hosted on GitHub, but the majority of the real conversations are elsewhere.


> frustrated at the time it takes to be as productive in something like c

Don't worry, no is productive in something like c

> After being stuck with a succession of scripting languages that weren't doing it for me

I am saddened yet also consoled everyone that likes Go comes from the scripting languages. That's such a low bar to beat!


Yeah. That's why it's about as successful as Dart.


I guess the political wars of JavaScript vs Dart, ChromiumVM and Chrome team dropping Dart on the floor, causing the departure of the original design team, kind of helped to Dart's success.

The political wars at Google with Dart are quite visible from outside, with Fuchsia picking up Flutter, and strangely the future of Android UI looks pretty much like Flutter, after too many times asking Android team about what was their opinion on Flutter for Android development at IO Fireside, meanwhile the developers' survey has had questions about how much we cared to see it supported on Kotlin multi-platform.

So yeah, had Chrome decided to push Chromium VM no matter what, Dart would be as successful as Go by now, after all younger generations don't seem to have any problem being Chrome developers.


Dart is an example of what happens to a language when corporate support is taken away. People lose confidence in the language.


Right. Programing languages by advertising companies have high adoption rate.


You're saying that as if it's not true

How many languages are there released by advertising companies?

Just to show the influence, python was an obscure programming language until Google started using it.


Actually no, Zope was quite famous during the first .com wave.

But Python has had many interesting sponsors throughout the years, not only Google.


A good example lies in Kotlin, as well.


Well, dev-oriented projects by Google and Facebook fair well...


I would think that would be a knock against it with the reputation of Google abandoning projects.


Java has genetics and it is many times more popular than Go. I'm not sure absolute adoption of Go is a good way of divining programmers opinions on genetics.


The popularity compared to what? How do the numbers stack up?


Oh, I'm not by any means saying it's the most popular language. I'm just comparing strictly based on the comment, people who like go vs people who will never use it because of its lack of generics.


>I wish they would just freeze the language and not add anything. I like it the way it is.

And a big share of users wishes they add generics - judging from it being the #1 voted feature in the annual Golang polls.

Not to mention the potential users that are put off because it doesn't have Generics...


Once they add generics, I will stop laughing at the language, but still probably won't use it. There's very little if anything it adds over C# or modern Java.


Until Docker or Kubernetes fad doesn't go away, having to deal with Go is something that those of us that rather use C# or modern Java have to face, so it will help if the language catches up with modern times.


But those large codebases will not be updated for some time. Or do you mean that at least new features could be written using generics?


The latter, as I always mention, platform languages always have the edge even if not as fancy as guest languages.

In the context of Docker and k8s, Go is the platform language so to speak, and although there are extension points for other languages, one has less integration headaches when using Go as well.


True. I think really a lot of people who are clamoring for generics in Go would already be working with more productive languages.

Generics is mainly for users who have committed to Go and new productive language features could possibly help them.


On the other hand, programmers don't always pick which languages they get to work with.

If I'm forced to use a language, it might as well have Generics than not...


At the moment it has something very valuable those languages don't have: A lack of Generics. Once they add Generics it will just be competing with those languages on the same turf.

It might not be for you, you may rely heavily on Generics in your daily work flow.

If I need generics in my work, I reach for Rust or C++. But when I want to write an easily maintainable microservice that's not trying to reinvent the wheel or need some clever datastructure to handle the work, I reach for Go, since that is what it's good at (at the moment).


How is having generics/templates to reinvent the wheel?

The one thing that put me off the most about using C for everything is lack of a common list/vector/map/set standard library for all types. Instead I reinvent the wheel in each project. Go cheats in this regard with compiler magic and that just pisses me off. Atleast you can in theory do printf in iso C.


How is being compiled the same turf as running in a VM?


I'm reminded of this Rob Pike quote from 2015 about what Go was trying to avoid:

"Java, JavaScript (ECMAScript), Typescript, C#, C++, Hack (PHP), and more [...] actively borrow features from one another. They are converging into a single huge language." [0]

[0] https://www.dotconferences.com/2015/11/rob-pike-simplicity-i...


I still find the most insightful Rob Pike statement (and the one that maybe induces a bit of forgiveness) that can give an idea for why Go is the way it is to be from this slightly older talk:

"The key point here is our programmers are Googlers, they're not researchers. 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 be able to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt."

https://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Fr... at 20:33


Wow that's really condescending.


yes, but it isn't false


i mean... it's at least a bit surprising. the programming course at my uni (java) got to generics within the first year... i'm sure the hiring requirements at google are a bit higher than that?


and got people worrying about such generic things instead of the problem. It's not the fact that its hard or not, it's just yet another thing to keep in mind when you should be solving issues. Managing time is important, juniors no matter how smart, are juniors because they were not part of the industries before, they are getting the hang of having stuff in production and maintaining it, also managing time to ship, how much "generic" should the code be.

Go just makes you productive by removing lots of things to think about. I'm not saying that generics should or shouldn't be part of v1, I'm just saying that go lacking features to make juniors more productive is a feature


As opposed to us who only use features developed by Bell labs.


As it stand today, there is some elegance in its simplicity, but the lack of generics makes it unergonomic to write libraries. It's a good language to build applications, though.

This is less to do with the language and more about the standard library, but it has tons of cross-platform quirks that I feel aren't handled well. For example, Rust's standard library makes cross-platform work less footgun-filled, IMO.


I think the team is doing an excellent job with carefully and methodically evolving the language.


Has there been discussion on just creating a golang managed collections library that's generic and not adding general generics into the language?


Erik Naggum: "… if you think in terms of the imminent end of the world, _everything_ is soon food for the great garbage collector in the sky and whoever is not scrambling in panic looks like they aren't moving and have been passed by or are dying. … like, if you aren't using today's fad language in the very latest version of the IDE, you'll be left behind. aaaugh! but it's good that some people run like they are scared out of their wits. if they suddenly disappear over the edge of a cliff, a good number of people will notice in time and _not_ follow them."

Of course, this was part of an email thread around Common Lisp's popularity in 1999 (https://www.xach.com/naggum/articles/3141310154691952@naggum...) but I think it's more broadly applicable and still relevant two decades later.

Anyway, if you really want a "static" language target, perhaps push hard for official standardization (ANSI, ISO...). Standards encourage a lot of nice things, which admittedly are possible without standards, but less incentivized... For example, I can still write ANSI C as the gods intended, compile other ANSI C written decades ago, using a plethora of compilers across time (including the current year with the latest optimizations) so long as they claim to implement that standard and so long as the code is actually ANSI compliant. Such compilers might implement later standards too, or custom extensions -- but that's ok because it tends to be that I can easily make use of such code and such code can easily make use of mine à la carte! No jihad must be waged on all old code to update it under threat of being relegated to time-capsuled VMs.

But regardless, things will change, even if you have an island of stability from your standard. This isn't necessarily bad, because in order for there to be any improvement, there must be change. "Not every change is an improvement, but every improvement is necessarily a change."


With the little detail that ANSI C written decades ago most likely contain UB that a modern C compiler will gladly take advantage of, with all the nice consequences that it entails.


> I think we should start putting weight on stable unchanging software.

I think that they are just afraid of the income to stop coming in... so they keep working.


You can always stop upgrading and join the python2.7 crowd (apparently not as big as it appeared it would be a few years ago).


Python 3 upgrade was a complete disaster that took over a decade. They should have just called it a different language name and started at 1.0.

Edit: And, if Go doesn’t learn from Perl and Python’s mistakes it is going to suffer greatly.


I disagree, Python is now stronger than it was years ago. Now all companies that I interact with are magically on Python 3.

They were also estimating that it will take this long.

IMO they should give shorter time to upgrade, because everyone was waiting to absolute last minute to migrate.


Then hopefully the language will be forked and we can have go++, with generics, the ability to build cross platform gui apps and much more rejoicing.


> I wish they would just freeze the language and not add anything

> I think we should start putting weight on stable unchanging software

You would probably like CL then.


I think the go authors have had a reasonable balance of this when adding new features. Generics are quite useful.




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

Search: