Why Generics?

218 points by johnvega 5 years ago | 254 comments
  • iainmerrick 5 years ago
    Maybe this is unfair, but it’d be great if the Go devs could just say “generics will work similarly to [C# / Java / Swift / D / whatever], except that we’ll address [problems] with [adjustments]”.

    Rather than going through this whole rigmarole of resisting adding generics too early because all existing implementations are bad, then slowly reinventing the wheel from scratch, then finally ending up with something pretty similar to one of those other languages anyway.

    It’s OK not to make something completely new and different. It’d be useful to explicitly say which language(s) you’re borrowing from because you can then more clearly call out the differences and explain the reasons for them.

    • grumdan 5 years ago
      > because all existing implementations are bad

      I'm also not sure why in OOP-land, generics are this crazy experimental weird feature, when in functional languages, people figured out how to implement parametric polymorphism (the original term for generics) in quite reasonable ways. I get that subtyping adds some complexity, but overall I don't understand why such a basic way to build abstractions is so controversial in (some) OOP languages. If anyone has some context on why this is more difficult to have in Java-like languages, I'd be curious to hear it.

      • gizmo686 5 years ago
        Inheritance makes generics difficult.

        For instance, if A < B (B extends A), What is the relationship betwern Array[A] and Array[B]?

        If you are just reading the array, you would want Array[A] < Array[B]. If you are writing to the array, you would want Array[B]<Array[A]. If you are doing both, you want Array[A] to have no relation to Array[B].

        This problem doesn't come up in ML style languages because they do not make use of inheritence.

        • justinhj 5 years ago
          It comes up in Scala. The solution is to have notation to specify the variance of types.
          • cousin_it 5 years ago
            That seems like a problem with inheritance + mutability, not inheritance on its own. After all, if B is a subtype of A, then we can make List[B] a subtype of List[A] as long as lists are immutable. Appending an A to List[B] returns List[A], what's the problem? :-) In fact some ML style languages (like OCaml) do have inheritance and it works fine with generics. Some generic types (like lists) will be covariant, others (like comparators) will be contravariant, combinations of the two will be invariant, and it all can be automatically inferred.

            Which of course doesn't change the fact that imperative languages trying to combine generics + inheritance + mutability are in for a world of hurt.

            • rowanG077 5 years ago
              It's not so difficult. It's just covariance and contravariance. C# has long solved this issue. https://docs.microsoft.com/en-us/dotnet/csharp/programming-g...
              • ernst_klim 5 years ago
                > in ML style languages because they do not make use of inheritence.

                Except for OCaml and Scala (or any other ML supporting subtyping), where you could simply define type's variance.

                • thundergolfer 5 years ago
                  Why in the case of writing to the array would you want Array[B] < Array[A]?
                • evmar 5 years ago
                  That's a really great question!

                  One other factor is that functional languages typically are theory first, implementation second, while non-functional languages tend to more often have the language features follow whatever the implementation admits. I know for Go they fretted a lot about how you'd efficiently compile generics, which is not something that comes up when you're designing System F or whatever.

                  But I believe that subtyping has a massive impact on generics, particularly in OOP languages where people expect to use lots of subtypes. There are all of these new questions around not only bounded polymorphism but also variance and mutability and how inference works.

                  Even TypeScript, which is following a lot of the design decisions already established by C# with the same person behind both, is still kinda just meandering around the design space and continuing to make changes to the semantics in new versions.

                  • hajile 5 years ago
                    If go ever showed people the awesomeness of StandardML or Ocaml/ReasonML (and their amazing type systems), I think the language would lose a lot of users.
                    • weberc2 5 years ago
                      This is confusingly phrased. Do you mean "If Go people were ever shown ... ML"? I would totally drop Go for an ML language if any of them had a sane syntax, usable build tooling (including native, static compilation by default), and a (single) decent standard library.

                      A super awesome type system is worthless without the basic requirements for scalable software development.

                    • iainmerrick 5 years ago
                      Just to be clear, I don’t think all existing implementations are bad, that was my (possibly unfair) caricature of the Go devs’ position.
                      • pvg 5 years ago
                        I can't think of a popular OO language where they are considered a crazy experimental feature. One historical reason for a certain reticence early on was people were unhappy with C++ templates.
                        • 5 years ago
                          • idnefju 5 years ago
                            ad-hoc polymorphism is where it shines. Such as the typeclass in Haskell or modules in OCaml
                            • RivieraKid 5 years ago
                              > I'm also not sure why in OOP-land, generics are this crazy experimental weird feature

                              It's not, it's an essential, basic feature.

                              • darkr 5 years ago
                                I’d say in Java they’re still not quite there, being implemented via compile-time type erasure and runtime type-assertions.
                                • notus 5 years ago
                                  Depends who you ask I guess
                                • kragen 5 years ago
                                  Golang doesn't have subtyping.
                                  • baby 5 years ago
                                    It makes code unreadable.

                                       void lol<A, <B, C<D>>, E>()
                                    • filleduchaos 5 years ago
                                      Pretty much all syntax is unreadable if you don't know the lingo. For example, try presenting the ubiquitous

                                          for (int i = 0; i < 10; i++) {}
                                      
                                      to ten random people without prior programming experience and see how many of them can correctly tell you what all that means. Similarly,

                                          { a, b in a > b }
                                      
                                      is probably not very clear to people who don't write Swift and perfectly lovely closure syntax to people who do.

                                      There's language syntax that's actually unreadable, for instance due to using names that obscure or otherwise don't clearly express what a construct is/does or using the same operator/keyword for too many different context-dependent purposes. I don't quite think the sheer presence of angle brackets makes code unreadable, any more than the sheer presence of curly braces or parentheses do.

                                      • Negitivefrags 5 years ago
                                        That isn't even close to valid C++.
                                    • shaded-enmity 5 years ago
                                      What is your point? Serious question.

                                      If you tell me, for example, that Go generics are going to be like C# generics, then I have to be familiar with the full semantics of C# generics. Essentially you tell me that in order to understand X I have to understand Y first, that's not good. Consumers of your language are not, for the MOST part, PLT nerds.

                                      • iainmerrick 5 years ago
                                        I’d compare it to e.g. the work on async/await in Rust, where the discussion seems more directly “we like this feature that C# pioneered and JS has adopted, here’s how we plan to adapt it to make it work well with Rust.”

                                        Admittedly, the Rust async/await RFC and the Go contracts proposal both discuss prior art in sections towards the end, so they are actually similar in that respect. Maybe it’s really just a question of tone and messaging, and the particular discussions that tend to end up on HN.

                                        • shaded-enmity 5 years ago
                                          Fair point, however I think that you're mistaking language design discussion in a closed group of PLT invested people, and a blog post targeted at general audience.

                                          Visiting https://rust-lang.github.io/async-book/ I don't see any mentions of neither C# nor JS. The key difference here is the audience.

                                        • jayd16 5 years ago
                                          >then I have to be familiar with the full semantics of C# generics

                                          Or you could research the very detailed discussion and documentation available on the topic of C# generics.

                                          • shaded-enmity 5 years ago
                                            How is your suggestion not equivalent to "be familiar with full semantics of C# generics"? How does that help me with being productive using Go's implementation of generics, which has fundamentally different type system and syntax to begin with?
                                          • mcguire 5 years ago
                                            The big advantage is that PLT nerds (Who else are you going to learn a programming language from?) already know the ugly, hairy bits of Y and how to work around them. The alternative is for X to invent new ugly, hairy bits.
                                            • vkou 5 years ago
                                              > then I have to be familiar with the full semantics of C# generics.

                                              Presumably, by the time the feature ships, the golang.org/doc entry on generics will not consist of just 'lol, they are just like C# generics, docs.microsoft.com, chum'

                                            • weberc2 5 years ago
                                              It seems like you’re objecting to the messaging (not referencing an existing language, which doesn’t work for people not familiar with the implementation of that language) and also that, at its inception, Go didn’t pick (randomly?) a language off of which to model its generic implementation. Am I misreading?
                                              • iainmerrick 5 years ago
                                                Well, there doesn’t seem to be a lot of discussion of alternatives at all, so I can’t really see what design and implementation decisions are actually being made. Most likely I’m just looking in the wrong place, and those discussions are taking place elsewhere.

                                                I guess my complaint is that this talk, like all the other updates on their progress on generics, implies that Go generics exist in a vacuum, whereas in reality there’s a ton of prior art that could usefully be referenced.

                                                Edit to add: this particular talk is focused on syntax details. Those aren’t unimportant but they’re a small part of the whole picture. As I commented on the detailed Contracts proposal, the decision to add contracts rather than simply using interfaces (as in Java and C#) seems significant but isn’t explained.

                                                • jerf 5 years ago
                                                  It was beaten unto death in github repo issues, mailing list topics, and wiki pages soliciting real-world examples.

                                                  This post is basically a conference talk transcript. More stuff is in: https://go.googlesource.com/proposal/+/4a54a00950b56dd009648... including several callouts to other languages.

                                                  It didn't all hit HN, or perhaps more accurately, it probably did all hit HN but didn't all get upvoted because how many times does HN need to chew on it in a month?

                                                  • weberc2 5 years ago
                                                    As jerf mentioned, there has been lots of talk; every single time the question of generics is raised here, /r/programming, or any Go-specific forum, it's addressed.

                                                    With respect to interfaces vs contracts; interfaces are about runtime polymorphism while contracts are about compile time polymorphism. This is an important difference when you consider []interface{Foo()} vs Slice(contract{Foo()})--an instance of the former can contain elements of varying concrete types while an instance of the latter can only contain elements of the same type. The other important detail is that interfaces only abstract over a single type while contracts support multiple type parameters (a single contract could specify a visitor type and a vistee type, for example).

                                                  • jayd16 5 years ago
                                                    Referencing existing work is not an rare or fanciful concept. If you're not familiar with prior work that's referenced in a paper then you can research that prior work as well. If prior work has not been referenced or addressed its usually considered a flaw.
                                                    • dalksfjid 5 years ago
                                                      >objecting

                                                      Reads more like suggesting to me. And, a helpful one.

                                                    • kragen 5 years ago
                                                      > if the Go devs could just say “generics will work similarly to [C# / Java / Swift / D / whatever], except that we’ll address [problems] with [adjustments]”.

                                                      This is basically how C++ was designed, and it turns out not to work very well; the [adjustments₁] for [feature₁] turn out to introduce not only unanticipated [problems₁] with [feature₁] itself but also new and previously unimagined [problems₂] with [feature₂]. So the Golang designers prefer to take a much more cautious approach than the Lumbergh approach you're suggesting. So far it seems to have worked out well — the language is not without its compromises, and it's substantially more complicated than it was at first, but it's a very reasonable compromise.

                                                      • iainmerrick 5 years ago
                                                        I don’t agree with your point, but I applaud your use of Unicode.
                                                        • kragen 5 years ago
                                                          Well, consider C++ inheritance combined with object nesting; you get slicing copies.

                                                          Or constructors combined with static objects; you get the static initialization order fiasco.

                                                          Or constness with template functions; you get two, four, or eight copies of each generic function in your source code according to which things are const.

                                                          Or (compile-time) overloading with (run-time) overriding; you get C++’s weird “hiding” rule about the other overrides you didn't override.

                                                          Or separate compilation with implicitly instantiated templates; you get geological build times as the compiler instantiates the same templates in every .C file and then throws away all but one of the identical instantiations at link time. (To be fair, this is far from the only reason C++ compiles slowly.)

                                                          Overriding combined with type conversions through implicitly invoked constructors (and implicit referencing and implicit casting to const) gives you annoying bugs that are unnecessarily hard to figure out.

                                                          Cleanup from exceptions via RAII combined with C’s unspecified argument evaluation order led to a situation where resource leaks during certain kinds of operations couldn't be avoided reliably, a bug in the language definition that wasn't noticed for several years, though I think it's fixed now.

                                                          The grammar is undecidable because of the number of different things that have been added, which sounds like a hyperbolic joke but is actually literally true, and a significant obstacle to implementing something like gofmt for C++.

                                                          The combination of template parameters using <> for parameters, the traditional longest-leftmost tokenization rule, and the >> operator for bitshifting made foo<bar<baz>> an unexpected syntactic pitfall, one that is now fixed.

                                                          There wasn't an exception-safe version of the STL for a number of years, which isn't really an interaction between templates and exceptions —a non-template container had to deal with the same exception-safety problems— but it did mean that fit quite a while you could use the STL or exceptions but not both.

                                                          This is far from the extent of the problem. The C++ FAQ consists largely of affirmations of the form, “Doing [reasonable thing 1] works, and [reasonable thing 2] works too, but if you do them both, you will die horribly for your immorality.” It's exaggerating about the death part but the surprising problems are quite real.

                                                          I don't hate C++, and I think it's the best existing language for some problem spaces, but it's very much the poster boy for unexpected problems arising from interactions between features.

                                                          As far as the keyboard goes, https://GitHub.com/kragen/xcompose and http://canonical.org/~kragen/setting-up-keyboard are your friends.

                                                      • helper 5 years ago
                                                        If you're just going to copy another language there really isn't much of a point in making a new language. Go is not java, or c# or rust.

                                                        Part of the explicit goal stated by the go team is that generics must still feel like go. If you slapped java generics onto go it would not feel like go.

                                                        • karmakaze 5 years ago
                                                          For my own benefit, I agree with this. I just want a more usable language now. Something like ad-hoc structural typing as in TypeScript with aliases seems close.

                                                          For the future of languages I appreciate the clean slate effort. Go has been about scoping out a use area sticking a leg there and coming up with something that works well there. At the same time I dont think there will be anything revolutionary, just something that seems simple and compact. I wish them great success and us a short wait.

                                                          • owaislone 5 years ago
                                                            Probably not as much as you'd like but I think the detailed proposal does talk about borrowing from Ada.
                                                          • jsgo 5 years ago
                                                            Generics with Reflection was the first gut check I experienced while working after completing college and getting an ASP.NET job. Like 2-3 weeks into said job.

                                                            Had to do an application that dealt with 4-5 forms (can't remember). Like 300 fields on the bigger ones, smaller ones 50ish. I started out on one that was mid-200. I'm coding the way I was taught in school: object set object properties based on txtWhatever.Text. Like 240ish times. I can't remember how many lines of code were in this code behind, but it was substantial.

                                                            I turn it in, it works. Go me, let me go on to the next one. The senior guy on the team does one of the smaller forms. But he uses generics and reflection to basically iterate over all of the fields on the form and sets them to the ephemeral properties on this generic object in like 8-9 lines of code. Then there was the rendering code that was vaguely similar.

                                                            Added bonus: 99% of his code behind could be copy and pasted over to the newer forms and handle all of the work related to getting/setting form values. After the code proved to work for a few weeks, replaced the massive code behind with call to his code (passing in the form object and the generic to be set and used later) with the same result and one area to manage code and it isn't an insanely large code behind file (got better with not one filing everything in time too).

                                                            Not saying generics and/or reflection are a silver bullet (I don't feel they are. Rarely so do they end up being the thing I go for), but it was definitely eye opening that straying from "see spot run" code could be advantageous. And that I wasn't "good to go" already.

                                                            • elpakal 5 years ago
                                                              Chiming in here as a Swift dev - I find its generics system incredibly helpful and end up writing something that uses generics about once a month. To those Go programmers who think they will never use them - it’s worth a little learning, and once you do you will find more ways to use them to make your code more applicable.
                                                              • Vendan 5 years ago
                                                                Chiming in as a fervent Go dev that's also a huge fan of generics: Generics are awesome, but always seem to add a ton of complexity. Everyone starts with just "oh, `func Reverse(slice []T)` is so obvious" kind of thing, but that's like saying `fmt.Println("Hello World")` is simple. It's simple cause you are doing a simple thing.

                                                                That said, I do want generics to come to Go, just... with an emphasis on what Go is, not just "here, let's replicate X's generics in Go". I am interested in the contracts implementation.

                                                                • Nevermindmine 5 years ago
                                                                  > Generics are awesome, but always seem to add a ton of complexity

                                                                  The team I work in use generics all the time and I'm not sure what complexity you are referring to. Care to elaborate? Is it some edge cases or are you talking about from a compiler perspective or something else?

                                                                  To me, not having generics is like saying let's skip handling bools and just store them in strings as "true" or "false". It's such a weird thing from my point of view.

                                                                  • Vendan 5 years ago
                                                                    Compiler perspective (fast compiles are a core part of Go, IMO), various tradeoffs(fast compile? fast runtime? binary size? Pick 1 or 2), and seeing code bases that get out of control with generics and such.

                                                                    Note that, for all of that, I'm still in favor of adding generics in Go, as I do see the value they can add. I'm just pointing out that "bashing" on Go devs on not knowing what generics are or how they can be useful is both non-productive and probably generally wrong. Plenty of us are saying "Man, if I had generics, this would have been less code/cleaner/more reusable!", just the other various tradeoffs outweigh the actual cost of using a different language. Go's ability to drop a very junior dev (or just one that has never use Go) into a codebase and have them be almost immediately productive is incredible.

                                                                    • nevir 5 years ago
                                                                      I think TypeScript is a good example of one extreme. You've got conditional types, literal types, type mapping, and a bunch of other very advanced parameterized types.

                                                                      (I also think it makes sense for TypeScript given JavaScript idioms; it mainly falls over when the caller has to interpret some very complicated error messages, however)

                                                                      • baby 5 years ago
                                                                        Try to read code that abuses generics you’ll see what GP means.
                                                                        • bushin 5 years ago
                                                                          "protocol can only be used as a generic constraint because it has Self or associated type requirements"
                                                                        • pknopf 5 years ago
                                                                          Pettifoging. I don't care what people do with them.

                                                                          I know how to use them. They are valuable to me.

                                                                        • AceJohnny2 5 years ago
                                                                          > To those Go programmers who think they will never use them - it’s worth a little learning, and once you do you will find more ways to use them to make your code more applicable.

                                                                          There was a story I came across once. It went something like this:

                                                                          The proponents of every gizmo think their gizmo is superior to the others, because it's got these useful features that the others lack, and isn't encumbered by the weird useless stuff those other languages have.

                                                                          If only they spent time to understand those "weird useless features"...

                                                                          • mikeash 5 years ago
                                                                            This is the Blub Paradox. http://wiki.c2.com/?BlubParadox
                                                                            • Vendan 5 years ago
                                                                              What is it when you know about the power of features of the "higher level" languages, like generics, but still chose the "blub language" because of other reasons, like ease of hiring devs?
                                                                            • chc 5 years ago
                                                                              I think you're talking about the Blub Paradox, by the guy who started this site.
                                                                              • AceJohnny2 5 years ago
                                                                                Huh. Yeah, that's exactly it. Funny coincidence :)
                                                                          • jknoepfler 5 years ago
                                                                            The decision to overload parentheses to express generic type is the only part of this spec I find nauseating. It doesn't scan well, and doesn't have a precedent in any major generic implementation I'm aware of. <, [, @-annotation... I don't care. Just don't mush it into the function declaration with the same syntax that encloses parameter.
                                                                            • weberc2 5 years ago
                                                                              Agreed, specifically it creates ambiguities in parsing (for computers but worse: for humans). Given Foo(x), you can’t tell if it’s a function call or a generic type without knowing what x refers to. You need context from afar to disambiguate.
                                                                              • enneff 5 years ago
                                                                                You can tell if it’s a function call or a generic type based on where it is used; the local context. Function calls are either statements or expressions. Types appear in declarations.
                                                                                • shhsshs 5 years ago

                                                                                      a := Bar(baz)(buzz)
                                                                                  
                                                                                  Is Bar a `func(some) func(thing) other` or is it a `func(type T)(some) other`? You need to know what “baz” is to be able to tell.
                                                                                  • weberc2 5 years ago
                                                                                    Reverse(x)(y)

                                                                                    Is that a function that returns a function or a generic Reverse function specialized over type x, invoked with argument y?

                                                                                  • saturn_vk 5 years ago
                                                                                    Some helpful syntax highlighting will probably help with these cases, I should think.
                                                                                  • ohnoesjmr 5 years ago
                                                                                    So much this.
                                                                                  • parhamn 5 years ago
                                                                                    That time of week to rehash all the Go Generics comments!

                                                                                    https://hn.algolia.com/?query=generics&sort=byPopularity&pre...

                                                                                  • moomin 5 years ago

                                                                                        Go 3: Why HKT?
                                                                                        Go 4: Why homoiconicity?
                                                                                        Go 5: Why uniqueness and borrowing?
                                                                                    • gclaugus 5 years ago
                                                                                      I am ok with this progression.
                                                                                    • olooney 5 years ago
                                                                                      What is HKT?
                                                                                      • mrkeen 5 years ago
                                                                                        I'll give the 'why' rather than the 'what'. In most mainstream languages you take a List<Int> and substitute for List<X> without changing the implementation of List. But there's another substitution you could have made, which is L<Int>. HKT allows you to parametrise L over Int, in the same way you were able to parametrise List over Int.
                                                                                        • icedchai 5 years ago
                                                                                          Thanks for the practical, plain English definition. As someone many years out of school, it is appreciated.
                                                                                        • clhodapp 5 years ago
                                                                                          Higher-kinded types. Generics that take generics as parameters. They allow things like writing a function that both takes and returns any container type you can map over with different (defined) element types. Given how hard arity-0 generics have been to get into Go, I suspect that the chances of HKT making it are slim to none (but I think that the grandparent knows that and is just being funny).
                                                                                          • sli 5 years ago
                                                                                            Generics are to types what HKT are to type signatures. In functions, they usually map to arity. That is, an arity mismatch is are a higher-kinded type mismatch. An easy (if not totally accurate) way to view them is like doubly-generic types.

                                                                                            If you have some type A, it has the kind * . If you have some function from A -> B, it has the kind * -> * .

                                                                                            • jsjolen 5 years ago
                                                                                              I've decided that it's the same as having a simply-typed lambda calculus with one type (*) and function types living inside of your type system. Is this correct at all?
                                                                                            • mping 5 years ago
                                                                                              Higher Kinded Types
                                                                                              • 5 years ago
                                                                                                • 5 years ago
                                                                                                  • eslaught 5 years ago
                                                                                                  • sjapkee 5 years ago
                                                                                                    So, ten years and Go will be production ready.
                                                                                                  • haolez 5 years ago
                                                                                                    Personally, I prefer the current interfaces-based solution to generics. It's a little verbose, but keeps the language simple.

                                                                                                    However, I think that the people we should be listening most are the ones developing huge projects in Go, like Kubernetes. Would having generics with this new contracts thing make it easier to develop and maintain e.g. Kubernetes? I'm truly curious.

                                                                                                    • btilly 5 years ago
                                                                                                      Which interfaces-based solution?

                                                                                                      The one used by sort is a hack that only works for some of the things that you would want to do.

                                                                                                      The one where you use introspection performs badly and isn't typesafe.

                                                                                                      The tree implementation in the article cannot be done in a safe and performant way in Go today.

                                                                                                      • haolez 5 years ago
                                                                                                        The one mentioned in the article.

                                                                                                        It's not a hack: it's a runtime equivalent that requires that your type implements some interface.

                                                                                                        • btilly 5 years ago
                                                                                                          It is a hack. The article lists a whole series of things that are standard in other languages that you can't do in go. Here are some examples:

                                                                                                            Find smallest/largest element in slice
                                                                                                            Find average/standard deviation of slice
                                                                                                            Compute union/intersection of maps
                                                                                                            Find shortest path in node/edge graph
                                                                                                            Apply transformation function to slice/map, returning new slice/map
                                                                                                          
                                                                                                          And here are data structures that other languages have but go does not:

                                                                                                            Sets
                                                                                                            Self-balancing trees, with efficient insertion and traversal in sorted order
                                                                                                            Multimaps, with multiple instances of a key
                                                                                                            Concurrent hash maps, supporting parallel insertions and lookups with no single lock
                                                                                                          
                                                                                                          If it were not a hack, then go would not have these limitations.
                                                                                                      • silasdavis 5 years ago
                                                                                                        Probably yes: https://medium.com/@arschles/go-experience-report-generics-i...

                                                                                                        Many smaller projects would benefit too. I would like to build a typesafe tree for an efficient sorted map, and to be able mergsort over multiple trees of different types. It would allow some extremely useful channel combinators for doing rather common things like safely shutting down a service with some background processing. Often these things leak and a often I find myself spawning more go routines just to map between types or to stop generic interface types infecting the rest of the API.

                                                                                                        • jerf 5 years ago
                                                                                                          I have been vigorously pro-generics since the beginning, and this is the reason why: I want generic data structures. Arrays&slices and maps are great, and they really are the 90/10 solution a lot of the time, which is precisely why putting direct support into your syntax for the two of them is so very, very popular, but that other 10 comes up.

                                                                                                          Plus, there are some generic data structures that will really work well in Go, like, for instance, an immutable tree. Granted, it'll still take some care to use properly in Go as it does not have "const" or anything like it, but it can still be done. The problem I have is not with accidental mutation, but that I just don't want to sit there and implement the immutable tree code. (Trees are great, but they're really tedious to write in the best of times, and nightmares to debug in the worst.)

                                                                                                          I'm not terribly interested in trying to jam functional programming into Go; I may make light use of map/filter/reduce but even if this was fully implemented it would still be a fairly unpleasant experience (function that return "a value and an error" aren't much fun to map and can't hardly "chain" at all). But I've missed being able to just grab a particular data structure a few times.

                                                                                                      • noncoml 5 years ago
                                                                                                        Generics and Interfaces solve different problems
                                                                                                        • ci5er 5 years ago
                                                                                                          Yes - but don't they get contangled?

                                                                                                          How would you re-orthoganize the problem statement? (Statements, actually)

                                                                                                        • dotaheor 5 years ago
                                                                                                          Yes, I think. Now, the kubernetes project uses too many code generators, which makes it is to extend.
                                                                                                          • saturn_vk 5 years ago
                                                                                                            I take it you've never actually read the K8s source code.
                                                                                                            • hinkley 5 years ago
                                                                                                              I'm a little surprised the word 'mixin' appears nowhere in that article.

                                                                                                              Josh Bloch argued against the interface solution in Java (and in particular, read-only versus read-write interfaces), claiming there would be too many interfaces and it would confuse users, and that didn't sit right with me. To me it's his second-biggest sin against Java, and it's tied to the first.

                                                                                                              The only truly unforgiveable one is UnsupportedOperationException. The guy who wrote the collections API for Java didn't know the first thing about the Liskov Substitution Principle, and gave the world an implementation that violates it because the alternative would have been too difficult for people to understand? Rot in hell forever, Josh. And take your Effective Java with you to throw on the pyre. I can't write effective Java and it's partly your fault.

                                                                                                              At the time I was experimenting with my own language API design, so I sat down and figured out how many interfaces it would take. I came up with around 20% more than the selected design. You'd think it would be bigger, but the critical observation is that a lot of generic collections vary only on write operations.

                                                                                                              Read operations are often identical, and if the surface area for reads is small, then a functional programming style is more reasonable. Which may explain why so many functional programming languages appear to other people to have an anemic collections API. What I'd love to know is if any of them use different implementations under the hood for small sets/lists versus large ones. If they do, I don't hear anybody bragging about it.

                                                                                                              • dang 5 years ago
                                                                                                                Oh dear. Personal attacks are not ok on HN, regardless of whom you're attacking. Please stick to the site guidelines, no matter how passionately you feel about the Liskov Substitution Principle.

                                                                                                                https://news.ycombinator.com/newsguidelines.html

                                                                                                                You obviously have a good point to make, but it needs to be done without firebombs.

                                                                                                                • rsc 5 years ago
                                                                                                                  > Rot in hell forever, Josh. And take your Effective Java with you to throw on the pyre.

                                                                                                                  Well that seems uncalled for.

                                                                                                                  • hinkley 5 years ago
                                                                                                                    It’s fairly difficult to come to terms with an “everything was going pretty well until...” moment and doubly so when it can be personified.

                                                                                                                    Once we broke LSP, a cascade of similar ideas started showing up with regularity, especially in J2EE. I used to be able to go on at some length but now it’s more “I hope I never meet this guy because it’ll be awkward as hell.”

                                                                                                                  • ben509 5 years ago
                                                                                                                    > The only truly unforgiveable one is UnsupportedOperationException. The guy who wrote the collections API for Java didn't know the first thing about the Liskov Substitution Principle, and gave the world an implementation that violates it...

                                                                                                                    The implementation perfectly follows it because the LSP simply requires identical behavior, and the contract clearly states it may[1] throw an exception. All the implementations "may" throw an exception. Sorry, but they correctly lawyered the LSP.

                                                                                                                    > I came up with around 20% more than the selected design.

                                                                                                                    But `add` can throw 5 different exceptions depending on restrictions your implementation wants to place on a given collection, does it allow for all that? In terms of making an interface that was small and reusable by many projects, runtime exceptions are a pretty good compromise for a standard library.

                                                                                                                    [1]: https://docs.oracle.com/javase/7/docs/api/java/util/Collecti...

                                                                                                                    • hinkley 5 years ago
                                                                                                                      No they most definitely are not. One implementation receives a message. The other categorically rejects it. I cannot substitute them.
                                                                                                                    • extempore 5 years ago
                                                                                                                      Of course they do. Not sure why it’s something to brag about or not to brag about though, it’s an implementation detail. Scala for instance uses custom classes for each size set up to a certain threshold.
                                                                                                                    • YawningAngel 5 years ago
                                                                                                                      Kubernetes is a transpiled Java project, so yeah, Java-like features would definitely make it easier :P

                                                                                                                      I think idiomatic golang works pretty well without generics in most cases, the big problem for me is that functional programming is essentially impossible without them.

                                                                                                                      • yureka 5 years ago
                                                                                                                        Can you provide some resources on what makes you think Kubernetes is a transpiled Java project?

                                                                                                                        That's definitely not the case from what I know/understand...

                                                                                                                      • jjtheblunt 5 years ago
                                                                                                                        https://en.wikipedia.org/wiki/Kubernetes says original Kubernetes was all C++.
                                                                                                                        • eshyong 5 years ago
                                                                                                                          If you read the article more closely, it says that Borg was written in C++. If you watch the video linked by @tuvan below, you'll hear the speaker (who is a contributor) mention that the original authors of Kubernetes wrote the first version in Java, which was rewritten in Go.
                                                                                                                      • archy_ 5 years ago
                                                                                                                        Agreed on keeping the status quo, adding generics makes it really easy to write bad code and increases mental overhead. Simplicity is what we should be going for, not having generics should've been kept as a selling point.
                                                                                                                        • silasdavis 5 years ago
                                                                                                                          This may be practical from the point of view of 'top level applications' in Go. But there is a lot of murk in pure Go implementations of databases, and datastructure heavy libraries that could be avoided and lead to better testing and less duplication. If you find it simpler to avoid generics that ought to be possible under this design.
                                                                                                                      • twodave 5 years ago
                                                                                                                        Generics and interfaces go hand in hand IMO, especially in an application with heavy emphasis on data persistence. This way you can compose a class of some interfaces, pass it to a persistence layer (using a generic constraint of something common to all inputs of that layer), and then the persistence layer can check for all the interface types it cares about saving and pass those pieces off to whatever lower-level piece of code handles that one thing.

                                                                                                                        Generics enable you to avoid having 10 slightly different implementations of the same thing (even if dependencies are shared, you're still going to have 10 copies of plumbing without generics). Being wise about when and when NOT to use generics is to me the most important factor.

                                                                                                                        In our shop we tend to not introduce a new generic class/method until something gets painful (unless it's plainly obvious from the beginning). Because of this we usually begin to notice and reason about patterns in our code that seem common enough to warrant refactoring and whether the complexity of a generic implementation would be worth lowering the maintenance burden of copy/pasting said pattern all over the place. It's a case by case decision.

                                                                                                                        Having generics available at least allows us to make that decision for ourselves.

                                                                                                                        • wrs 5 years ago
                                                                                                                          The examples I’d like to see worked out fully, which he mentions in passing, are encapsulation of concurrency patterns (parallelization, work queues, cancelling, etc.). It’s not that big a deal to write Max as a function or even inline, whereas there are serious practical pitfalls and common mistakes when doing real work with channels. It would be a lot more effective to fix these by writing library code rather than writing Gophercon presentations.
                                                                                                                          • Filligree 5 years ago
                                                                                                                            Why generics, indeed?

                                                                                                                            There must be an answer to this, but I've never seen a good response to why they aren't implementing parametric types and (single-parameter) typeclasses instead.

                                                                                                                            Simplicity? Yes, but generics are hardly any simpler.

                                                                                                                            • mda 5 years ago
                                                                                                                              For me, generics make api designer's life harder, but api user's life easier. A good enough reason for me.
                                                                                                                              • silasdavis 5 years ago
                                                                                                                                Perhaps I'm misunderstanding, but I would have thought go already implements typeclasses and this proposals extension to the interface semantics is a parametric typeclass?

                                                                                                                                Would you mind elaborating?

                                                                                                                              • mitchellh 5 years ago
                                                                                                                                It might be fun to share my viewpoint from an angle that's probably fairly unique.

                                                                                                                                I've started a number of large, highly deployed Go projects: Terraform, Vault, Packer, Consul, Nomad, and numerous libraries and other things. I started a company that employs hundreds of full time Go developers. Go has been one of our primary languages since Go 1.0 (and I used it prior to that).

                                                                                                                                Let me start by saying that there are _definitely_ cases where generics are the right answer. Usually when I talk about generics people tend to assume I disagree with the whole concept of generics but I certainly do not. Generics are useful and solve real problems.

                                                                                                                                Adding this paragraph after I already wrote the rest: this whole comment ended up sounding super negative. I'm voicing concerns! But, I think that the design proposal is exciting and I am interested to see where it goes. There are definitely places generics would be helpful to us, so please don't take my negativity too strongly.

                                                                                                                                ## Technical Impact

                                                                                                                                Having written these numerous large, complex systems, I believe there are less than 10 instances where generics would've been super helpful. There are hundreds of more times where it would've been kind of nice but probably didn't justify the complexity of implementation or understanding.

                                                                                                                                This latter part is what worries me. I've worked in environments that use a language with generics as a primary language. It's very easy to have an N=2 or N=3 case and jump to generics as the right way to abstract that duplication. In reality, the right answer here is probably to just copy and paste the code because the knowledge complexity of using generics (for both producer and consumer) doesn't justify it, in my opinion.

                                                                                                                                As a technical leader, I'm not sure how to wrestle with this. Its easy today because generics just don't exist so you have to find a way around it. But for a 150+-sized org of Go developers, how do we have guidelines around when to use generics? I don't know yet. I guess that bleeds into human impact so...

                                                                                                                                ## Human Impact!

                                                                                                                                Something that is AMAZING about Go today is that you can hire a junior developer with no experience with Go nor any job history, have them read a few resources (Tour of Go, Go Spec, Effective Go), and have them committing meaningful changes to a Go project within a week.

                                                                                                                                I don't say this as a hypothetical, this has happened numerous times in practice at our company. We don't force or push any new hires to do this, but Go is so approachable that it just happens.

                                                                                                                                I love it! It's so cool to see the satisfaction of a new engineer making a change so quickly. I've been told its been really helpful for self-confidence and feeling like a valuable member of a team quickly.

                                                                                                                                The Go contract design document is about 1/3rd the word count of the entire Go language spec. It isn't a simple document to understand. I had to re-read a few sections to understand what was going on, and I've used languages with generics in a job-setting and have also been a "professional" Go dev for 9 years.

                                                                                                                                So what worries me about this is technical merits aside, what impact does this have on learning the language and making an impact on existing codebases quickly?

                                                                                                                                I really like what Ian said about attempting to put the burden of complexity on the _author_ using generics, and not the _consumer_ calling that function. I think that's an important design goal. I'm interested to see how that works out but I'm a bit pessimistic about it.

                                                                                                                                ---

                                                                                                                                I have other viewpoints on generics but those are the two primary ones that stand out to me when I think about this proposal going forward.

                                                                                                                                • mcguire 5 years ago
                                                                                                                                  "Having written these numerous large, complex systems, I believe there are less than 10 instances where generics would've been super helpful."

                                                                                                                                  If you wrote Python, you'd probably be saying, "there are less than 10 instances where type declarations..."; you could make similar statements about concurrency or a host of other features.

                                                                                                                                  And you'd be more or less right.

                                                                                                                                  Here's the deal: a language with generics is very different from a language without generics. You write different code, you solve problems differently, you think differently. This is why they should have had generics in version 1.0 and why adding them later seems so underwhelming to some of us. Generics have a lot of advantages, but you are going to be looking at a bizarre mixture of programming styles for a long time.

                                                                                                                                  • jasonwatkinspdx 5 years ago
                                                                                                                                    > The Go contract design document is about 1/3rd the word count of the entire Go language spec.

                                                                                                                                    They're quite different documents, so I think this is somewhat unfair and misleading. The go spec doesn't spend prose on explaining rationals, alternatives, historical references, etc.

                                                                                                                                    • ClayShentrup 5 years ago
                                                                                                                                      I see the use for generics all the time. I came from Ruby, where we have enumerable so you get standard constructs like map, find, first, last, each_cons, etc. Because Go lacks them, people constantly reimplement these things with less intention-revealed code using ad hoc for loops. Ugh.

                                                                                                                                      Thus you see very little use of collection pipelining in Go. https://martinfowler.com/articles/collection-pipeline/

                                                                                                                                      Generics are such a powerful and useful idea. Bring it on.

                                                                                                                                      • steveklabnik 5 years ago
                                                                                                                                        Your parent is quite familiar with Ruby. :)
                                                                                                                                      • jakevn 5 years ago
                                                                                                                                        This reflects my experience with Go to a tee. (Well, minus being a prolific library contributor, thanks for that!)

                                                                                                                                        Prior to using Go professionally, I scoffed at the language and wrote it off as an extreme form of Blub paradox. Having worked in languages with generics, as well as languages with advanced type systems (Haskell, Rust, Scala), it seemed like a huge step back.

                                                                                                                                        Initially, I did have a problem with the lack of generics, because I leaned on the feature regularly when writing software. Four years of professional use later and I can say that I am very much glad for the lack of generics. It is almost always straightforward and easy to read and understand Go code that someone else has written. The same cannot be said for the other languages I've mentioned.

                                                                                                                                        For the problem domain we are using it in (devops), it has been a godsend. The company makes use of many different languages from various paradigms, yet anyone can pick up Go quickly if they want/need to contribute to or deeply understand our tooling.

                                                                                                                                      • aczerepinski 5 years ago
                                                                                                                                        Mixed feelings about this. One of my favorite things about Go is that it's a small and relatively simple language. It's a "fast enough" language without the steep learning curve of Rust. Too many features that make sense individually could change the calculus to "might as well use Rust".
                                                                                                                                        • aldanor 5 years ago
                                                                                                                                          I'm not so sure about the "steep learning curve of Rust" stereotype anymore. If you are comfortable with low-level programming languages in general, in a few days you can get yourself started fairly quickly with Rust to the point where you will still battle with compiler re: borrowing and related things, but will be able to write functional code. Coming from pure Python/JS will be tough, but it will be the same with any other low-level language.
                                                                                                                                          • aczerepinski 5 years ago
                                                                                                                                            My work is a Ruby/JS shop, and we have some Go in production as well. We definitely need a little hand holding to ramp anybody new up on the Go codebases. In many cases our devs haven't used types, pointers or any equivalent of goroutines & channels. I've written just barely enough Rust to say there are even more concepts that would be new to my team.

                                                                                                                                            Even with Go being comparitvely simpler, I could go either way on whether it was the right choice to add it to the stack.

                                                                                                                                            • LandR 5 years ago
                                                                                                                                              > In many cases our devs haven't used types, pointers or any equivalent of goroutines & channels.

                                                                                                                                              How do you manage to get a job as a developer without having ever learned this stuff?

                                                                                                                                              Are these people that are just self taught straight to javascript / ruby?

                                                                                                                                              I mean, are CS course nowadays so bad that students come out of them without understanding things like type-theory, pointers etc

                                                                                                                                        • fabiensanglard 5 years ago
                                                                                                                                          I hope this doesn't happen. I love golang because it is simple and easy to read. Both will go away when generic programmer start to write unreadable meta-programming class which "you don't need to understand, just use them".

                                                                                                                                          I admire golang devs for being opinionated and stand up for the core lines of their language so far.

                                                                                                                                          I see generic as renouncing these principles.

                                                                                                                                          • icholy 5 years ago
                                                                                                                                            What are you on about? The current draft doesn't enable any type of meta-programming.
                                                                                                                                            • theli0nheart 5 years ago
                                                                                                                                              I don't think it's as clear-cut as you make it seem. Generics greatly reduce the amount of code we need to read in exchange an slight increase in abstraction. In my opinion, the tradeoff is worth it, especially given that Go already has abstractions that are more difficult to grok than generics, which, all things considered, aren't that hard to understand.
                                                                                                                                              • baby 5 years ago
                                                                                                                                                It’s not worth it because most people tend to abuse them.
                                                                                                                                                • saturn_vk 5 years ago
                                                                                                                                                  do you have any statistics that can back your claim?
                                                                                                                                              • owaislone 5 years ago
                                                                                                                                                May be you could share feedback with us and the designers about which parts you think will be hard to understand? This is a valid concern but only way to address this is to specify and share as feedback to the proposal.
                                                                                                                                                • jasonwatkinspdx 5 years ago
                                                                                                                                                  This design does not permit metaprogramming.
                                                                                                                                                  • tylerflick 5 years ago
                                                                                                                                                    This. If I really need generics I'll use a different language.
                                                                                                                                                    • takeda 5 years ago
                                                                                                                                                      This reminds me the discussion about first version of iPhone how so many people were advocating why adding copy&paste functionality was a bad idea.
                                                                                                                                                      • theshrike79 5 years ago
                                                                                                                                                        More like people were advocating against the shitty Copy&Paste phones used to have.

                                                                                                                                                        When it came out, it was possible to C&P pictures to emails and other fancy stuff that wasn't possible before.

                                                                                                                                                        • weberc2 5 years ago
                                                                                                                                                          Agreed. There are good objections to generics; this is not one of them.

                                                                                                                                                          EDIT: If any Apple employees are reading this, I really wish autocorrect would stop confusing generics and generics. :)

                                                                                                                                                        • goatlover 5 years ago
                                                                                                                                                          Must every popular language evolve into C++ or Common Lisp?
                                                                                                                                                          • snazz 5 years ago
                                                                                                                                                            I wonder if there's room for a language that is small, allows for nearly limitless abstraction, and still has great tooling. Go is (or, you could argue, was) small, and now has better tooling, but is just beginning to increase its ability to create abstractions. Common Lisp is large (only 200 pages fewer in its spec than C++, if I remember correctly), has unparalleled tooling (like the don't-unwind-the-stack debugging and SLIME), and really good abstraction power. Scheme is small and consistent (unlike CL), and also can create similarly advanced abstractions, but is missing some of the tooling that CL has enjoyed for eons.

                                                                                                                                                            I'll be really cool to see a language that feels consistent, tight, well-engineered, and small; can create powerful abstractions similar to what can be achieved using CL macros and CLOS; and has an awesome debugger, editor interop, interactive programming with a REPL, build tools, etc.

                                                                                                                                                          • meddlepal 5 years ago
                                                                                                                                                            That's great if you get to pick the language you use for every project. Not all of us get that luxury.
                                                                                                                                                            • weberc2 5 years ago
                                                                                                                                                              And also only works if your project requirements are entirely foreseeable from day 0.
                                                                                                                                                        • Pxtl 5 years ago
                                                                                                                                                          Go has generics. What it actually lacks is user-defined generics.

                                                                                                                                                          Which shows the absurdity of the situation. The fact that it has generics demonstrates that generics are a useful and important feature. And yet they think their provided generics cover every possible use-case of generics that you will reasonably need in to use in Go.

                                                                                                                                                          • Vendan 5 years ago
                                                                                                                                                            And yet, the core devs have never said they don't want generics, only they didn't want a poor implementation.

                                                                                                                                                            Also, there's a bit of hilarity about commenting this on a blog.golang.org where the first sentence is "This article is about what it would mean to add generics to Go, and why I think we should do it." being posted by a core Go dev....

                                                                                                                                                          • zeveb 5 years ago
                                                                                                                                                            Not certain I like that this is now valid Go:

                                                                                                                                                                func Foo (type T) (t T) (t T, err error) { … }
                                                                                                                                                            
                                                                                                                                                            Seems like an awful lot of parentheses in a single line!

                                                                                                                                                            It's a bit tricky to read, because 'generic function' here means something subtly different from what 'generic function' means in CLOS …

                                                                                                                                                            • mseepgood 5 years ago
                                                                                                                                                              It's not more parentheses than in a method definition:

                                                                                                                                                                  func (a A) Foo(x int) (n int, err error) { … }
                                                                                                                                                              
                                                                                                                                                              Also your line isn't formatted properly. It should be:

                                                                                                                                                                  func Foo(type T)(t T) (t T, err error) { … }
                                                                                                                                                            • merlincorey 5 years ago
                                                                                                                                                              As a functional leaning programmer, I think it's striking that the resulting draft is essentially a curried function whose first parameter is the type!

                                                                                                                                                                  func Reverse (type Element) (s []Element) {
                                                                                                                                                                      first := 0
                                                                                                                                                                      last := len(s) - 1
                                                                                                                                                                      for first < last {
                                                                                                                                                                          s[first], s[last] = s[last], s[first]
                                                                                                                                                                          first++
                                                                                                                                                                          last--
                                                                                                                                                                      }
                                                                                                                                                                  }
                                                                                                                                                              
                                                                                                                                                              This is later called like:

                                                                                                                                                                  Reverse(int)(s)
                                                                                                                                                              
                                                                                                                                                              Which if this were a curried function, would also be callable like:

                                                                                                                                                                  Reverse(int, s)
                                                                                                                                                              
                                                                                                                                                              Now I wonder if facilities for currying functions might be a higher level addition that could result in the same thing (so long sa we can pass bare types, which is part of this change as well).
                                                                                                                                                              • mcguire 5 years ago
                                                                                                                                                                I hate to tell you, but you're on your way to dependent types.
                                                                                                                                                              • baby 5 years ago
                                                                                                                                                                I have two comments to make about this proposaL:

                                                                                                                                                                1. The type should indicate a generic, not a new syntax. This is better because it is easier to parse for the human eye. For example:

                                                                                                                                                                  func Reverse(first _T, second _T)
                                                                                                                                                                
                                                                                                                                                                2. Since all of what generics are is a compile-time code generator, I suggest that Golang forces developers to explicitly list what types are using the generic:

                                                                                                                                                                  generics(Add) = {int, string, car, food}
                                                                                                                                                                  func Add(first _T, second _T)
                                                                                                                                                                
                                                                                                                                                                This list can be added to, after importing the package:

                                                                                                                                                                  Import “thing”
                                                                                                                                                                
                                                                                                                                                                  generics(thing.Add) += {stuff}
                                                                                                                                                                
                                                                                                                                                                This makes code very explicit about its generic functions. It also allow readers to understand exactly where the function is used.
                                                                                                                                                                • jayd16 5 years ago
                                                                                                                                                                  If I'm understanding correctly, contracts are a way to implement compile time duck typing? If that's the case I think its a pretty neat twist on generics.
                                                                                                                                                                  • SomaticPirate 5 years ago
                                                                                                                                                                    One of the things I like most about this is that Ian includes the simple mistake in the first function. It’s a bit humbling and acknowledges the fact that even the best of us often make trivial mistakes. It also helps make the point that even the simplest code needs a basic test and adds another argument in favor of generics on the premise of duplicating tests.
                                                                                                                                                                    • wwarner 5 years ago
                                                                                                                                                                      I feel pretty good reading this. I like that you can write listMyType := List(MyType). I'm still a bit dubious about contracts; they're so similar to interfaces. If there was a way to derive or relate a contract to an interface that would help me.
                                                                                                                                                                      • sp527 5 years ago
                                                                                                                                                                        This process took way too long. I've already moved back to Python3 and am super happy with it. The truth is most software doesn't really need the performance benefit Golang offers and you can code up something in Python in at least half to a third of the time it would take in Golang. Aside from agility, there's one other benefit that imo matters a lot: reduced LoC. If there's one thing I've learned in my career, it's that you can never really have too few lines of code, provided it achieves the same result as a hypothetical more verbose alternative.

                                                                                                                                                                        I will admit though that I miss Go's CSP implementation and error-handling convention. Maybe I'll come back to it in the future after they add generics and fix the dependency system.

                                                                                                                                                                      • clamprecht 5 years ago
                                                                                                                                                                        Such a succinct article. I wish journalists could explain things this well.
                                                                                                                                                                        • sansnomme 5 years ago
                                                                                                                                                                          I think another area of Go that could use improvements is a more portable standard library optimised for embedded and OS dev. A lot of people want to use Go as a "systems language" and do drivers etc. in it. But the standard library don't have good support for freestanding, or at least it's not a priority. C and Rust and other languages designed for usage in a non-hosted environment have very clear delineated areas of runtime that requires assembly, manual interfaces for IO/memory allocation etc. Go's runtime by default assumes the presence of an operating system.
                                                                                                                                                                          • jerf 5 years ago
                                                                                                                                                                            "Go's runtime by default assumes the presence of an operating system."

                                                                                                                                                                            It also assumes the existence of several megabytes of runtime and enough RAM to feasibly use GC, which if nothing else is probably a real mess when it comes to drivers.

                                                                                                                                                                            What you probably need, rather than being a second-class citizen of the main Go language indefinitely, is a separate dialect that is close to Go, but can go its own way if it makes sense, like: https://tinygo.org/

                                                                                                                                                                            • sansnomme 5 years ago
                                                                                                                                                                              There is nothing wrong with GC. There exist plenty of network stacks in production that are written entirely in Go (See Docker/Kubernetes et alia). There are also operating systems that have GCs, such as Oberon or the few C# OSes written by MSFT and others. As long as care is taken to isolate hard real-time requirements when needed, a GC is perfectly fine. There is a real advantage to Rust's style of explicitly marking no_std. After all, what's the point of using stuff like tinygo (other than for performance/resource reasons) if it cannot run most of the existing Go libraries?
                                                                                                                                                                          • jordiburgos 5 years ago
                                                                                                                                                                            This looks as an strategy to keep people (and HN) talking about Go.
                                                                                                                                                                            • mlevental 5 years ago
                                                                                                                                                                              why are people obsessed with simplicity? there's a quotation my Einstein that I like to keep in mind: "make things as simple as they can be but no simpler". the implication being that if you make things too simple then you actually break things. lack of generics makes for software that's actually more complex than it needs to be. Take for example Swift: lots of complex features (protocols, all manner of functional transformations, generics, enums, structs, iterators, objects with many method qualifiers, etc) but really nice and efficient to program in.
                                                                                                                                                                              • dimgl 5 years ago
                                                                                                                                                                                I have yet to find one practical application for generics in the apps I've built in Go.
                                                                                                                                                                                • stouset 5 years ago
                                                                                                                                                                                  And I had yet to find a single practical application for closures, right up until the moment I started using Ruby (and later, Rust).

                                                                                                                                                                                  Turns out that they’re so useful in practice that they’ve been bolted on to—as far as I can tell—nearly every language in widespread use today. None of these languages “needed” such an improvement. Billions of lines of Java and C# were written without this feature. And yet today it would be virtually unthinkable to release a language without them.

                                                                                                                                                                                  • dimgl 5 years ago
                                                                                                                                                                                    I feel like closures are a consequence of having functions as first class citizens, so it's not exactly a direct comparison. But I guess I see your point.
                                                                                                                                                                                  • pknopf 5 years ago
                                                                                                                                                                                    That's crazy. I've seen people implement templating of go files to support generics in Go because it's serves a valuable purpose.
                                                                                                                                                                                    • Smaug123 5 years ago
                                                                                                                                                                                      Safety! Generics allow you to get [theorems for free](https://ecee.colorado.edu/ecen5533/fall11/reading/free.pdf), so generics make certain classes of error extremely hard to make.
                                                                                                                                                                                      • rad_gruchalski 5 years ago
                                                                                                                                                                                        Every project I’ve written so far in golang could benefit from generics.
                                                                                                                                                                                        • freetobesmart 5 years ago
                                                                                                                                                                                          but what is the benefit? How does your code change. Generics are a tail abstraction. Its the last abstraction that you are able to make to your code to reduce boilerplate. This usually means that is the least useful and in generics specific case the boiler place it reduces is minimal.

                                                                                                                                                                                          Its lack of impact is why I dont really care about the subject. Adding or removing generics to a project matters little. So why bother complaining. The class creation and encapsulation choices are much more impactful to future code edits.

                                                                                                                                                                                        • bbatha 5 years ago
                                                                                                                                                                                          If the std lib had functions that mapped to the "Slice Tricks"[0], like virtually every other language, I'd use them constantly. Sure I wouldn't write generic functions all that much, but calling generic code I would do every day and it would be a serious ergonomic, correctness, and readability improvement to have named functions for very common patterns like the slice tricks.

                                                                                                                                                                                          0: https://github.com/golang/go/wiki/SliceTricks

                                                                                                                                                                                          • iainmerrick 5 years ago
                                                                                                                                                                                            Right, I see this as the biggest benefit.

                                                                                                                                                                                            Go already has generic built-in maps, channels and slices, so clearly those generic types are useful.

                                                                                                                                                                                            If what I actually want is a multiset, say, it would be great to have a standard library class that looks and behaves similarly to map except it’s a multiset, rather than just having to use map and do all the little 1- and 2-line boilerplate tricks for the multiset operations. I can write shorter code that more clearly expresses my intentions, and reduce the risk of stupid little bugs in the boilerplate.

                                                                                                                                                                                          • kd0amg 5 years ago
                                                                                                                                                                                            Generics are more for developing reusable libraries than single applications.
                                                                                                                                                                                            • RHSeeger 5 years ago
                                                                                                                                                                                              I see you program in Blub (http://www.paulgraham.com/avg.html).
                                                                                                                                                                                              • mcguire 5 years ago
                                                                                                                                                                                                If you've never used a screwdriver, all you can say about screws is that they make crappy nails.
                                                                                                                                                                                                • icholy 5 years ago
                                                                                                                                                                                                  You've never used a data-structure other than the built in maps and slices?
                                                                                                                                                                                                  • whateveracct 5 years ago
                                                                                                                                                                                                    If you're writing loops that build up some accumulator, you could use generics. Even if you don't see that.
                                                                                                                                                                                                    • iainmerrick 5 years ago
                                                                                                                                                                                                      You could use generics for that kind of code, but that doesn’t necessarily mean you need them.

                                                                                                                                                                                                      If you’re thinking of functional stream operators, many people think plain imperative iteration is easier to write (and easier to read).

                                                                                                                                                                                                    • mlevental 5 years ago
                                                                                                                                                                                                      That's because you write a particular kind of program. Notice that there are no good ORMs or numerical libraries. Both of these are use cases for generics. Of course it doesn't help that the go community is convinced that ORMs are evil (which is just posthoc rationalization for being unable to write one).
                                                                                                                                                                                                      • dimgl 5 years ago
                                                                                                                                                                                                        Developers think ORMs are evil because they've had horrible experiences with ORMs in general. I'm one of them. The only ORM that I enjoyed using was Dapper, and it's barely an ORM.
                                                                                                                                                                                                        • reificator 5 years ago
                                                                                                                                                                                                          > Of course it doesn't help that the go community is convinced that ORMs are evil (which is just posthoc rationalization for being unable to write one).

                                                                                                                                                                                                          Yep. I held this opinion before Go came out, only because I couldn't write an ORM in Go.

                                                                                                                                                                                                          • kfoo020njdj 5 years ago
                                                                                                                                                                                                            “I can see the value so those that can’t are inferior.”

                                                                                                                                                                                                            You basically just post hoc rationalized their indifference for ORMs by making them sound incompetent

                                                                                                                                                                                                            As if there are no other arguments for avoiding them that perhaps seem valuable to people that are not you?

                                                                                                                                                                                                            It sounds reasonable to me you conjured the hot take, acknowledged it was post hoc rationalization on your part, but posted anyway, projecting your capacity for after the fact rationalizing onto ORM haters in the Go community.

                                                                                                                                                                                                        • astrobe_ 5 years ago
                                                                                                                                                                                                          > why are people obsessed with simplicity? > "make things as simple as they can be but no simpler".

                                                                                                                                                                                                          Those people are obsessed, precisely, with the "can be".

                                                                                                                                                                                                          • haolez 5 years ago
                                                                                                                                                                                                            C++ solves all problem that can be solved with Go, but with a lot more features.

                                                                                                                                                                                                            Why are we not using C++ where Go is currently being used? By your logic, this shouldn’t be the case.

                                                                                                                                                                                                            • wvenable 5 years ago
                                                                                                                                                                                                              I'm pretty sure C++ is used for exactly the game thing Go is used for. And C++ is used for a lot of other things as well. In fact, you will probably have trouble finding a problem that wasn't solved by C++ by somebody. Scientific computing, server process, CRUD applications, embedded applications, AI, graphics, programming languages, libraries, etc.

                                                                                                                                                                                                              C++ has a lot more features and therefore it's actually able to be used for a lot more things. People that don't need a language that can be used for every possible computing problem think that maybe C++ is a tad too complicated. Those people certainly have a point.

                                                                                                                                                                                                              • esarbe 5 years ago
                                                                                                                                                                                                                I don't think it's the feature-set that makes C++ viable for more situations than Go. In my opinion that's only because Go uses managed memory. That takes part of the runtime behavior of the code out of the hands of the programmer. This counts out Go for situations where you need precise control over runtime behaviour.

                                                                                                                                                                                                                That said; C++ is a ridiculously complicated language. I don't get why people think that Rust is difficult.

                                                                                                                                                                                                          • throwawayoo 5 years ago
                                                                                                                                                                                                            What are Generics?
                                                                                                                                                                                                            • mcguire 5 years ago
                                                                                                                                                                                                              "This article is about what it would mean to add generics to Go, and why I think we should do it. I'll also touch on an update to a possible design for adding generics to Go...."

                                                                                                                                                                                                              This is a situation where who is making the proposal is more important than the proposal.

                                                                                                                                                                                                              "By Ian Lance Taylor"

                                                                                                                                                                                                              Oh. Ok. I guess it's worth reading then...

                                                                                                                                                                                                              • 013a 5 years ago
                                                                                                                                                                                                                The proposed syntax feels like a caricature to me. That something like this could be easily possible:

                                                                                                                                                                                                                    func (c Connection) Read(type T Writeable)(into *T) (int, error) {
                                                                                                                                                                                                                
                                                                                                                                                                                                                This is quite securely inside shark-jumping territory.

                                                                                                                                                                                                                Also; I haven't seen Rob Pike's name really anywhere in these blog posts or discussions, or on any recent Go blog entry. Is he still involved with the Go project day-to-day? I always got the impression that he was one of the bigger anti-generics voices on the team internally.

                                                                                                                                                                                                                • monkeyfacebag 5 years ago
                                                                                                                                                                                                                  As far as I can tell, the latest proposal draft forbids type parameterized methods. One must admit the type parameter to the receiver or define a type parameterized function. I am making no claims about your broader point, only clarifying that your example is not permitted by the proposal draft. See https://go.googlesource.com/proposal/+/4a54a00950b56dd009648...
                                                                                                                                                                                                                • phlakaton 5 years ago
                                                                                                                                                                                                                  I do not think generics should be added to Go. It does minimalism and it does it tolerably well. Yet I enjoy using generics in other programming languages. If I had my druthers I'd be in Haskell-land in more than my spare time.

                                                                                                                                                                                                                  Hence, my modest proposal: Add generics, but make it a brand-new programming language with a totally different name.

                                                                                                                                                                                                                  Sadly, the name Blub is already taken. I propose we call it Glop. Or perhaps: Gong.