1. 51
    1. 27

      The comparison seems a bit forced. C++ is an extreme case of a language with generics. There are languages with generics that are quite compact.

      1. 10

        Eiffel comes to mind.

      2. 7

        Comparing generics in other languages to templates in C++ is comparing apples to ham burgers. I wouldn’t call templates “generics”. C++ templates are much more powerful. How powerful are C++ templates? Well, they are Turing complete…

        1. 2

          C++ templates turned into sth. noone has ever really planned. Many features Templates have are totally incidental.

          Templates have some very interesting interactions with other language features. Used in a creative way you can make pure compile-time functions return different values each time:

          int main () {
            int constexpr a = f ();
            int constexpr b = f ();
          
            static_assert (a != b, "try again");
          }
          

          http://b.atch.se/posts/constexpr-counter/

          1. 1

            now THAT’S some black magic right there.

    2. 38

      The constraints imposed by the lack of generics (and other things Go lacks) breed creativity

      Yes, like copypasting code.

      This is like the worst take on the reason not have generics.

    3. 19

      This is one of the most unpleasant, flamey threads I’ve seen on Lobsters yet…

      1. 7

        Seriously, this is scary! First we see that Lobsters is susceptible to systemd hysteria, and now Go generics, as well… Is no place safe?

        1. 3

          Let me tell you about my Vim configuration and why I don’t use Emacs…

          1. 7

            Ha! People don’t seem to get so vituperative about editors, though. I mean, people even suggest going “best of both worlds” with evil-mode.

            Systemd and Go are both run by small, strong-willed core teams who like to solve concrete problems, have a fairly consistent style of solving them, and provide detailed technical justifications for what they do, but don’t worry much about achieving global consensus before making decisions. Maybe that just inherently irritates people.

            1. 4

              The other topic I’ve seen technical people go crazy about lately is blockchains, and I got a bit of perspective from working with those for a while, because there it’s so obvious that there is this “political economy of technical decisions”, to coin a phrase, and forks can be extremely, ridiculously contentious.

              If systemd were just somebody’s pet project, they could do whatever they liked, but they’ve ended up in a position of power, as it were, because they’re the root process and upstream for most GNU/Linux distributions. I think the anti-systemd crowd should give up on trying to influence that project and go for exit rather than voice—the hard fork approach.

              Forks in regular open source take energy and cause some disruption, but at least they’re not blockchain forks. Just start working on removing that daemon and replacing it with your own solutions, and let’s live in peace, right? When has shouting on the internet ever solved anything?

              I would suggest forking Go to add generics but… they’re already working on it? Russ Cox himself says:

              After the release of Go 1, we continued to explore various possible designs for generics, and in April 2016 we released those early designs, discussed in detail below. As part of re-entering “design mode” for the Go 2 effort, we are again attempting to find a design for generics that we feel fits well into the language while providing enough of the flexibility and expressivity that users want.

              Some form of generics was one of the top two requested features in both the 2016 and 2017 Go user surveys (the other was package management). The Go community maintains a “Summary of Go Generics Discussions” document.

              Many people have concluded (incorrectly) that the Go team’s position is “Go will never have generics.” On the contrary, we understand the potential generics have, both to make Go far more flexible and powerful and to make Go far more complicated. If we are to add generics, we want to do it in a way that gets as much flexibility and power with as little added complexity as possible.

              So, uhh?

              1. 3

                forking systemd just means more systemd like init systems, not a good approach!

            2. 1

              Well, systemd appears to irritate people mostly for implementation details.

            3. 1

              vituperative

              It’s emacstuperative, you insensitive clod! ;)

            4. 1

              Absolutely. Nothing irritates engineers like having their chance to bikeshed taken away. Gnome is another great example of a system that generates tons of hatred, and yet… it’s by far the most popular desktop environment out there.

    4. 17

      I still don’t understand the backlash against “generics” (i.e. parametric polymorphism). If you’ve ever programmed in a dynamic language, then much of the code you’ve written in that language is generic, e.g. len() in python.

      “generics” is just a language feature to bring this flexibility to statically-typed languages. What is complicated about this? Writing val length : 'a list -> int is simpler than writing val length_of_int_list : int list -> int and val length_of_string_list : string list -> int.

      1. 20

        My guess is that you probably haven’t used Go. In particular, len is actually polymorphic in Go, but only because it’s a builtin function. Go does have interfaces, which provide some limited ability to write generic code. The famous thing that they don’t support well are generic type safe data structures. But they can sometimes support generic algorithms, for example, sorting.

        Either way, if you really, truly, don’t understand the backlash against generics and you want to, then there are a number of things out there explaining the draw backs. Russ Cox kind of kicked it all off with this blog post. You might reject his argument, which is fair, but you might at least understand it. ;-)

        If you keep searching, folks (like Ian Lance Taylor) have made some fairly involved proposals for adding generics to the language, and IIRC, they include reasons why they didn’t move forward. See here for a starting point. Note the links at the bottom.

        1. 6

          Oh, I didn’t understand it was a performance concern. My only Go experience was writing a fairly simple command line app. If the core team doesn’t accept a particular tradeoff between static and dynamic method dispatch, how did interfaces become part of the language?

          One option is to provide for both static and dynamic dispatch as language-level features, like Rust.

          1. 6

            I found the relevant portion from the generics proposal for you:

            Polymorphism in Go should be implementable both at compile time (by repeated specialized compilation, as in C++) and at run time, so that the decision about implementation strategy can be left as a decision for the compiler and treated like any other compiler optimization. This flexibility would address the generic dilemma we’ve discussed in the past.

            In other words, under this proposal, you wouldn’t get static vs dynamic dispatch as a language feature. Rather, it would be an implementation detail.

          2. 5

            One option is to provide for both static and dynamic dispatch as language-level features, like Rust.

            Yes. Read the Go 2 generics proposals for more on that point. (You may not like what you find.)

        2. 0

          Either way, if you really, truly, don’t understand the backlash against generics and you want to, then there are a number of things out there explaining the draw backs. Russ Cox kind of kicked it all off with this blog post. You might reject his argument, which is fair, but you might at least understand it.

          All he mentions is C++. I don’t think there’s any effort to benchmark generics, and I don’t think the algorithms involved in typechecking them are pathological. I really don’t see any fundamental problems with them, just complaints about C++ and C++ compilers.

          1. 6

            I provided other links. Go read them instead of trying to rehash everything with me, which I am absolutely not interested in doing because I don’t think you’re commenting in good faith.

      2. 9

        Generics bring complexity. People tend to over-abstract their code and to make it a lot less readable.

        1. 14

          Not using the right abstraction can also make your code harder to follow.

          In any case, not having a feature and then pretending that you only didn’t include the feature because of “bad” or “ivory tower” programmers is ridiculous and we can all see through the bullshit.

          1. 7

            No, it really is a feature. I can’t pretend I like it, because I’d rather have generics in Go, but I understand it and I’ll try to explain it:

            Go is designed around simplicity. Its whole design (minus the null pointer problem) helps you make simple, obvious and reliable codes. You don’t think much: you just build the thing the simple way. And reading the code of fellow programmers is easy too. You lose some power or elegance because of that but the programming flow is uninterrupted and remarkably quiet.

            Go is ideal for big teams because of that. You don’t have to dive into tricky modules and bugs are rarer and simpler than in most languages (with the possible exception of some concurrency problems).

            Not all languages share the same goal.

        2. 3

          This argument proves too much. Substitute generics<->functions.

      3. -1

        “Generics” in this context means C-style templates. You don’t need those in dynamic languages because you have a base class. You don’t need them in statically typed languages either where you can add a base class, but that’s not the world of C++ or Java.

        1. 1

          I’m not sure it has to do with inheritance. Dynamic languages allow for parametric polymorphism because values are boxed, and type errors are caught at runtime; you can write a function to append two lists, and as long you treat each element as a generic value (e.g not calling list_item.assumed_field), you’ve engaged in generic programming.

    5. 14

      Go strikes me as one of the most conservative programming languages available today. It’s small and simple, and every detail is carefully thought out. There are very few dusty corners of Go - in large part because Go has fewer corners in general than most programming languages. This is a major factor in Go’s success to date, in my opinion. Nearly all of Go’s features are bulletproof, and in my opinion are among the best implementations of their concepts in our entire industry.

      https://stackoverflow.com/questions/43059653/golang-interfacenil-is-nil-or-not

      1. 10

        Of all the noise that’s resulted, that’s probably one useful result. Somebody on HN posted a similar link. (https://dave.cheney.net/2017/08/09/typed-nils-in-go-2) It’s something I’d vaguely remembered, but it’s always good to have a refresher.

    6. 20

      I always find it kind of funny that Google didn’t want generics in Go, but hacked it into one of their projects: https://github.com/google/gvisor/blob/master/tools/go_generics/generics.go

      1. 26

        There are many people in google, surely not all teams agree on this issue.

        1. 16

          There’s also a bit of a difference between an implementation that works for one project and The Solution built into the language, which is supposed to (ideally) be a choice in the design space that’s fairly good across a broad range of uses. There are a bunch of solutions that work for various definitions of work, but the ones I’ve read all still have weird warts and edge cases (but different ones). Besides lower-level questions like how they interact with other parts of Go syntax and semantics, there’s also still quite a bit of disagreement, I think, on which of the basic tradeoffs in generics design are right for Go. Some people want Go generics more along the lines of ML-style parametric polymorphism or Java-style generics, while others want something more like C++ or D-style templates that instantiate specialized versions per-type. (The implementation linked above looks like the 2nd type.) Probably only one of these mechanisms will end up in the core language, not both.

          Edit: This “problem overview” from August 2018 has more details on the tradeoffs and current draft proposal.

        2. -2

          And yet apparently the language was shitty enough to force them to do this?

    7. 26

      I’m pretty surprised by the amount of hate for Go in the comments here. I definitely agree with the author. For me the simplicity of Go has been an absolute breath of fresh air. It really feels like a better C.

      C doesn’t have generics and yet you don’t hear people complain about that. Right now if you want a statically typed, garbage collected language, your only real options are Java (JVM languages) or Go. The cross platform support for C# is still pretty poor, and many of the smaller languages just don’t have the library support.

      I just don’t see the lack of generics as an issue right now, but I hope that the new generics proposals for Go2 get it right.

      1. 29

        Generics weren’t really a thing until 1973 with ML. C was released in 1972, so it gets some slack. Generics were pretty well understood for decades before Go came out which is why people go off about it.

      2. 13

        The problem is that many people aren’t advocating Go as a better C, but as better, period. And many other people are denouncing Go as a bad language, period. The result is polarization which shows up as ‘hate’ (I would prefer to call it ‘unmoderated negativity’, because I don’t know (and cannot really imagine) if people actually feel hate).

        It would be much nicer if everyone applied the principles of humanity and charity

      3. 6

        C has the preprocessor, which lets you build things like generic redblack trees. Of course, in go, you have go generate. So I think it comes out about even, but because the two features aren’t identical people don’t really consider them.

        For that matter, c++ templates frequently boil down to tons of duplicated code generation, which then the linker has to sift through. Go’s solution requires a touch more work, but eliminates a lot of eventual waste.

        1. 5

          C Preprocessir and go generate might be about equal in what they can do, but there’s no question that C Preprocessir has a lower barrier to entry for the basic things.

        2. 2

          Preprocessor a separate language and tool from C, though. It’s not like having the feature built into the language with the compiler being able to understand the context as it applies the feature.

      4. 5

        I’m not sure that I agree about the C# bit. Why do you say that the cross platform support is poor?

        1. 11

          Seriously, it feels bizarre using Mono for about a decade, yet people act like .NET only appeared outside of Windows when .NET Core was busy being born a few years ago.

      5. 8

        It really feels like a better C.

        So… if you ignore the past 30 years of academic research, it’s a good language? How exactly is that impressive?

        C doesn’t have generics and yet you don’t hear people complain about that.

        I’ve never used generics, and I’ve never missed ’em.

      6. 4

        I more or less begrudgingly agree. Every now and then I find myself wishing for generics or operator overloading in Go (not as often as I would have guessed)… then I remember how refreshing it is to be able to read some unfamiliar Go code and know that I don’t have to wonder what an innocuous looking “+” might be doing.

        1. 9

          You can have generics without operator overloading, though. See also: Java 5.

      7. 0
        1. 13

          Not in the sense that anyone cares about. It doesn’t allow for user-defined generic code – the library author has to write the specialized implementations ahead of time, and exhaustively enumerate what types their macro is generic over. This feature exists almost exclusively for the benefit of tgmath.h.

          C would have been better off without this poorly thought out solution.

    8. 9

      Nice article, and thanks a lot for sharing this part as well:

      I used to sneer at the Go maintainers alongside everyone else whenever they’d punt on generics. With so many people pining after it, why haven’t they seen sense yet? How can they know better than all of these people? My tune changed once I started to use Go more seriously, and now I admire their restraint.

      not many in this space are capable of changing their mind and admitting it:)

    9. 8

      Note that clumping templates of C++ with generics of other languages is like clumping apples with dead cats. They are very very different. With one (templates) you can do generic programming, with others (generics) you can’t. Generics in other languages throw away type information while C++ templates dont.

    10. 8

      In my opinion, generics are an imperfect solution to an unsolved problem in computer science.

      But what are viable alternatives to type parameters? Common alternative solutions are:

      • Dynamic types. Just cast at runtime. Dynamic languages work that way. Go probably works that way too, with its interface {}, most C implementations of type parametrization too. Some runtimes like V8 js even have almost compile-time monomorphization with JIT.
      • Macros allowing to do your own compile-time monomorphization, so it can be in library, not in compiler. I’m not sure, but looks like even C++ works similar to this way, because it has “templates” and not “type parameters”. Google’s generics.go and other similar hacks use this approach.
      • Manual monomorphization. Copy-paste the code and replace types. Also is an idiomatic approach in Go, when casting at runtime have too much cost (i.e. sorting array of generic values).

      The first approach looks the most promising, if you can afford performance overhead of dynamic dispatch and/or JIT. That’s why dynamic languages will be popular, probably, forever. Maybe it’s possible to have separate type checker, decoupled from compilation and monomorphization, using probably more general way than type parameters (I have no idea how this generalized checker might look, maybe refinement types or something like that).

      But I don’t get “we have no type parameters because we don’t have a problem that they solve” argument. It’s too turing tarpit’ish. X86 assembly also doesn’t have problem with not having type parameters.

    11. 7

      It wasn’t the central point of the article, but I found it very hard to let this quote pass:

      Go modules took the idea of dependency management and rethought it from first principles, then landed on a much more elegant solution that I think other programming languages will spend the next few years catching up with.

      Go has certainly started from scratch in it’s design of dependency management tooling, but - at least to me - feels very far behind other languages both new and old. It makes some of the painful parts of other systems much easier, especially in it’s attempts to minimise the impacts of updating dependencies, but makes a lot of things much harder that are already elegantly solved by other package managers (swapping implementations of dependencies or getting them from other sources, showing outdated packages, separating source code from distribution, providing an interface for other tooling to be built on top of the dependency manager, and so on).

    12. 22

      Hot take: $GOPATH is The Only Good Part of Go. I now clone all git repos as ~/src/github.com/user/project.

      Super hot take: Go is an anti-intellectual language. The attitude of the creators of Go sounds a lot like “hurr durr screw these academics with their dependent linear generic polymorphic magic types, we want the good old days of C back but with concurrency now” and “programmers can’t be trusted to use advanced constructs, just give them simple C stuff anyone can learn in a day”. Rob Pike thinks that “Syntax highlighting is juvenile”. WTF?

      Extra hot take: the most offensive part of Go is the internals of the main implementation. Don’t ever let people with a Plan 9 fetish design a compiler. Why? Just read the readme of c2goasm, a workaround that lets you call non-Go code without cgo overhead. And look at the Go assembler itself. If there’s one thing that AT&T and Intel syntax fans will 200% agree on, it’s that the Go/Plan9 syntax is an abomination. (Also it doesn’t fucking support the instructions (and even addressing modes!) you might need. Literally that documentation page tells you with a straight face to just encode your fancy instructions as byte constants: BYTE $0x0f; BYTE $0x6f; BYTE $0x00. Are you kidding me?!)

      1. 14

        Cold take: 99% of people programming in go will not be writing plan9 syntax assembly.

        1. 11

          99% of people programming in go are welcome to ignore anything about go internals. But I think people deserve to know that the internals are very weird.

          1. 7

            I heard/read that the rationale was that plan9 stuff might have been weird, but Rob Pike and Ken Thompson (soon followed by Russ Cox) were all deeply familiar with the entire toolchain and figured they could get cross architecture/cross OS compilation working quickly and build from there. It might have been a weird toolchain, but they did write it, so they were starting with a known quantity.

            1. 8

              That doesn’t sound like a great rationale for a production language sponsored by a huge serious company.

              Wait, actually, this is a very Google thing to do. There’s a history of big complex projects built at Google that are mostly incomprehensible to anyone outside of Google and don’t integrate well with the outside world. Like GWT.

              1. 9

                Google was only incidentally involved in the design of Go. Go was made by 3 smart people, and bankrolled by a “huge serious company”.

      2. 2

        Super hot take: Go is an anti-intellectual language.

        That’s good, actually.

      3. 1

        It’s an anti-“hurr durr I’m an intellectual so do as I say because I know what’s best for you” language and that is not a bad thing. Every single go team member probably has a more solid understanding of (any arbitrary aspect of) compsci than you do.

        1. 19

          Every single go team member probably has a more solid understanding of (any arbitrary aspect of) compsci than you do.

          … And therefore you aren’t allowed to have dissenting opinions?

          Come on now.

          1. 5

            Which part of my comment made you think I want to police opinions? I just made a counter argument to the “go is bad because it’s anti-intellechual” line, dunno how you got to the meta level. I do get the feeling now though that you would very much like to police my “dissenting” opinions, hmm?

            Anyways, Miles understands the point I was trying to make and put it quite well I think, so no need to elaborate on that.

            1. 1

              Your comment is based on an assumption that the OP isn’t as smart as Rob Pike et al.

              I don’t care about your opinion. Have whatever shitty opinion you want—that’s your prerogative.

              1. 2

                While that seems like a fairly safe assumption to me (for suitable meanings of “smart”), it is not actually a prerequisite to my point.

                All I am assuming is that the Go designers do in fact know a decent amount of compsci but chose not to include various concepts for reasons that go beyond “academics came up with it”, i.e. they evaluate ideas on their own merits, instead of assuming anything originating in academia is either good or bad. Now, obviously their reasons and decisions can be debated, but implying they boil down to nothing more than a dislike of academia is either dishonest or idiotic (or both) and contributes nothing of any value to the decision making process.

          2. 3

            No, but therefore you aren’t allowed to describe them as anti-intellectual. Intellectual giants aren’t anti-intellectual.

            1. 4

              Hmm. I am not sure you understand anti-intellectualism, but maybe it, as a concept, needs to change to be more inclusive of experience gained from years in industry.

              Calling Rob Pike et al, anti-intellectual makes sense from the text book definition because they’ve eschewed everything but garbage collection from academic CS from the last 30+ years, defining the language, instead, based on personal feelings from industry experience.

              I am certainly open to citations that suggest otherwise…please include the citation’s publish date as well.

              1. 5

                Just because academics have designed a feature, doesn’t mean that feature needs to exist, nor does it make the feature useful

                1. 3

                  Just because Rob Pike says no to a feature, doesn’t mean that the feature shouldn’t exist, nor does it make the feature not useful.

                  1. 4

                    Nobody is saying that Rob Pike’s word alone is a good reason to not have a feature in a programming language.

                    You say Rob Pike et. al. have ignored everything from academic CS from the last 30+ years. Maybe, but if you actually look at the last 30+ years of academic CS (in the area of programming languages) the most visible portion of it is an intense focus on very strongly and statically typed pure functional programming languages: ML derivatives, Hindley-Milner type inference algorithms extended to extensions of System F, dependent typing, etc.

                    What widely programming language out there, other than Haskell, doesn’t ignore everything from the last 20 years of programming language research at least? Java? C++? C#? Javascript? Python? Rust? What about Rust’s type system is actually based on research done in the last 20-30 years?

                    Parametric polymorphism is a lot more than 30 years old.

                    1. 4

                      Rust? What about Rust’s type system is actually based on research done in the last 20-30 years?

                      As a matter of fact, more than the Type System has been influenced by academia… https://doc.rust-lang.org/1.2.0/book/academic-research.html

                      As for the rest of the languages you mention… research is trying to unfuck C. C++ — I don’t follow its development well. Python has always ignored academic influences, and its creator has said some really dumbfounded things over the years, to boot.

                      Java was born directly out of industry, but over the years, heavy research (not sure how much is purely academic vs industry) has gone into implementation, the garbage collection algorithms, nio, the recent proofs if the type system’s unsoundness…

                      JavaScript was built in 2 weeks, but recent ECMAScript has authors like, Dave Herman, who has a PhD with a PLT focus from Northeastern…

                      So, I think your statement, and position are categorically wrong.

                      (Please excuse the lack of links, and brevity, I am on my phone and eating doughnuts)

                      1. 0

                        As a matter of fact, more than the Type System has been influenced by academia… https://doc.rust-lang.org/1.2.0/book/academic-research.html

                        And Go’s concurrency system is influenced by academia. Everything in every language is influenced by academia. What I asked was what about Rust’s type system was influenced by recent research, given that the criticism of Go is that its type system isn’t based on recent research.

                        As for the rest of the languages you mention… research is trying to unfuck C. C++ — I don’t follow its development well. Python has always ignored academic influences, and its creator has said some really dumbfounded things over the years, to boot.

                        All of this seems to suggest that being based on recent research isn’t actually a relevant factor for comparing how good languages are, and thus that the criticism of Go as not being based on recent research and being bad as a result, or bad because its creators ignore recent PLT research, or whatever, is clearly bogus.

                        1. 4

                          And Go’s concurrency system is influenced by academia. Everything in every language is influenced by academia. What I asked was what about Rust’s type system was influenced by recent research, given that the criticism of Go is that its type system isn’t based on recent research.

                          Your original “recent” was “within the last 20-30 years”. Incidentally, the thing from Go that is most often cited as “influenced by research” is it’s weird interpretation of CSP by Hoare, originally published > 30 years ago in 1978…

                          The Academic Research page I linked for Rust (Specifically, the Types Influence):

                          • Region based memory management in Cyclone (2002)
                          • Safe manual memory management in Cyclone (based on it’s references, after 2005)
                          • Typeclasses: making ad-hoc polymorphism less ad hoc (1997?)
                          • Macros that work together (2012)
                          • Traits: composable units of behavior (2003)
                          • Alias burying (2001?)
                          • External uniqueness is unique enough (2002?)
                          • Uniqueness and Reference Immutability for Safe Parallelism (2012)
                          • Region Based Memory Management (1994)

                          Now that I’m not eating doughnuts, nor on my phone:

                          All of this seems to suggest that being based on recent research isn’t actually a relevant factor for comparing how good languages are, and thus that the criticism of Go as not being based on recent research and being bad as a result, or bad because its creators ignore recent PLT research, or whatever, is clearly bogus.

                          What is a “good language”? It’s pretty subjective. What’s good to me, isn’t good to you. What’s interesting is how well the Blub Paradox, describes what’s going on here.

                          When I use Go, I cringe at the fact that I can’t safely create a closed enumeration that can’t be nil. You can do weird things with interfaces (in fact, there’s a solution in this very thread), but as soon as you do, then a value can be nil, and now you’re broken. Which leads me to the inclusion of nil, The Billion Dollar Mistake… somewhat hilariously proclaimed by the influencer of Go’s crowning feature, “Something CSP like,” go routines!

                          Many Go programmers I talk to suggest “being careful and using iota is good enough.” Those same programmers will say that “there’s no way you can be careful enough to use C.” I guess carefulness is a spectrum? I’d prefer computers to remove some of my need to be careful instead. After all, research has shown that computers are much better at it than humans…

                          So, when Go’s type system is a small step up from C in power, despite 47+ years of “we can do better than that,” you’ve gotta wonder what’s going on?

                          My theory is that years of developing operating systems with C taught the Go authors how to avoid getting shot with their foot gun. However, instead of destroying the foot guns, they figured, “well, if we keep the foot guns on a shelf and tell people not to touch them, they won’t get shot.” The people yelling loudly about Go not adopting PLT research are the people who clearly see the foot guns on the shelf, and the stool right next to shelf.

                          ~~

                          BTW, an important question that we’re not bringing up here is “what is even research?” Obviously, the folks making proposals to change Go are doing some sort of textbook definition research. Is it any different than Brian Goetz’s work on Project Valhalla, who is doing “research” within Oracle? Do we constrain the set of relevant articles to those appearing at a major conference, like OOPSLA, POPL, ICFP? That seems silly. A bigger question, for sure.

        2. 8

          Do you know the person you’re responding to or are you just insulting them because they said something you don’t agree with?

          1. 3

            I do not know them and I did not write what I did to insult them, just to put what they said in some context. My comment applies equally well to me and with some specific exceptions probably to everyone in this thread. No shame in not being a genius.

        3. 4

          that’s literally just more anti-intellectualism lol

          1. 4

            If you aren’t ready to admit that some kinds of intellectualism can be bad, I don’t think I have anything to say to you.

      4. 2

        Hot take: $GOPATH is The Only Good Part of Go. I now clone all git repos as ~/src/github.com/user/project.

        GOPATH is the single worst misfeature of any language I’ve ever used. Any language that tells me how to lay out my code, where to put it? I hate them all. Java forces you/encourages you heavily to put one public class per file. Blergh. Go forces you/encourages you heavily to use GOPATH. Blergh. Anything like that is just shit. C is one of the best, because all of its ‘module’ stuff is an emergent property of people using the language and its preprocessor, not some pre-designed over-engineered module system with namespaces and complicated lookup paths.

        Super hot take: Go is an anti-intellectual language. The attitude of the creators of Go sounds a lot like “hurr durr screw these academics with their dependent linear generic polymorphic magic types, we want the good old days of C back but with concurrency now” and “programmers can’t be trusted to use advanced constructs, just give them simple C stuff anyone can learn in a day”.

        That’s not anti-intellectual. It’s not fucking anti-intellectual to not want to write Haskell or some exceedingly overly complex reimplementation of the worst half of Haskell like most languages have become.

        Rob Pike thinks that “Syntax highlighting is juvenile”. WTF?

        Syntax should be readable without syntax highlighting.

        1. 7

          That’s not anti-intellectual. It’s not fucking anti-intellectual to not want to write Haskell or some exceedingly overly complex reimplementation of the worst half of Haskell like most languages have become.

          I thought you might want to know that this reads like you’re misdirecting your anger at Haskell towards programming languages as a whole. In general, it’s difficult to be told to accept something by someone who is not very accepting.

    13. 9

      Most people complaining about go not having generics are just using it an excuse to not pay attention to go and stick with whatever they use. If go did have generics they’d just complain about something else. Like it says in the article: plenty languages with generics do exist.

      I notice that many of them make the unprovable assumption that the go language designers didn’t add generics because they are ignorant of basic comp.sci concepts and techniques like hindley milner, parametric polymorphism, type inference. It’s really silly to think this, just consider the careers the go team have, they’ve been working on production compilers for decades. If you know about this techniques and you haven’t even built a compiler and OS then why would you expect them to be so much more ignorant than yourself?

      A lot of the complaint about generics comes from people who program in dynamically typed languages too. Like python or javascript or ruby. These languages can produce exactly the same runtime errors if you put the wrong typed object in a list as if you put the wrong typed object in a golang list built using interface{}. It isn’t fair to give dynamically typed languages a free pass while also making it a mortal sin that golang doesn’t implement parametric polymorphism.

      It’s really unfortunate that detractors of go have picked on this one aspect of the language design and inflated into such a big flamewar like emacs vs vim. The go language has a lot to offer and is a serious improvement over some of the existing tools like PHP for web application design. This is being overlooked since people just want to rag on the language for not implementing a feature they need for their comfort zone.

      1. 10

        We talked about this for far too long, and you don’t seem to have listened to any of the points at all. I’ll respond here with the same things I’ve said elsewhere simply for posterity.

        Most people complaining about go not having generics are just using it an excuse to not pay attention to go and stick with whatever they use. If go did have generics they’d just complain about something else. Like it says in the article: plenty languages with generics do exist.

        I’ve used Go. I had to figure out how to compile an undocumented application, test, and debug it. This seemingly simple task took me three weeks, and led me to the conclusion that I dislike three primary things:

        1. No generics. It leads to copy and paste code. As with all copied and pasted code, each iteration varies slightly. This leads to bugs and unpredictable behavior.
        2. Bad error handling. No tracebacks are automatically appended to errors, and any function that isn’t protected by a conditional error check is an error waiting to happen.
        3. Absolutely abysmal package management. I ended up using git bisect to try to figure out which release of a library was used to build the program. That is unacceptable.

        I notice that many of them make the unprovable assumption that the go language designers didn’t add generics because they are ignorant of basic comp.sci concepts and techniques like hindley milner, parametric polymorphism, type inference. It’s really silly to think this, just consider the careers the go team have, they’ve been working on production compilers for decades. If you know about this techniques and you haven’t even built a compiler and OS then why would you expect them to be so much more ignorant than yourself?

        This is an argument from authority. The language itself seems to lack many of the niceties that have emerged from computer science in the last few decades. I don’t know what Rob Pike knows; all I can do is judge based on his output and public statements. He’s produced a language that lacks generics, has terrible error handling, and had “just pull some code from Github” as its package management strategy. He wrote this code trying to prove that filter is useless.

        A lot of the complaint about generics comes from people who program in dynamically typed languages too. Like python or javascript or ruby. These languages can produce exactly the same runtime errors if you put the wrong typed object in a list as if you put the wrong typed object in a golang list built using interface{}. It isn’t fair to give dynamically typed languages a free pass while also making it a mortal sin that golang doesn’t implement parametric polymorphism.

        Yes, I program in dynamically typed languages. I don’t particularly like them, but they pay the bills: I’d rather make $X writing Python than $0 writing Haskell; you can’t use someone’s day job as a justification for why their informed opinions on other subjects are invalid. It smacks of “Ah, you want to improve society? And yet, you live in society!” “Gotcha!” idiocy.

        Furthermore, Python/Ruby/Javascript don’t pretend to be statically typed. Of course you can get runtime type errors in them. That’s part of the deal. On the other hand, Go has all the worst parts of static typing and yet has to throw it away on interface{} as soon as you need to write anything mildly generic. It’s very similar to Java (pre-generics, of course).

        It’s really unfortunate that detractors of go have picked on this one aspect of the language design and inflated into such a big flamewar like emacs vs vim. The go language has a lot to offer and is a serious improvement over some of the existing tools like PHP for web application design. This is being overlooked since people just want to rag on the language for not implementing a feature they need for their comfort zone.

        It isn’t inflated. It is a valid and obvious problem with the language. The thing that makes it a “flame war” is that the Go fans have glommed onto Rob Pike and the rest of the Holy Implementors as if they have access to some inaccessible truth, as if they are “intellectual giants” rather than simply being language implementors.

        I want Go to be a good language. It’d be great to have a language that compiles to static, native binaries and has a garbage collector and no GIL. That’s a surprisingly uncommon niche! Maybe the Go 2 proposals, which:

        1. Add generics,
        2. Improve error handling somewhat, and
        3. Standardize package management

        can improve the language into something that I want to use. Until then it seems really weird for you guys to be insulting anyone who has these complaints as ivory tower complainers with no valid points.

        1. 3

          We talked about this for far too long, and you don’t seem to have listened to any of the points at all.

          You say this and then you repeat exactly the same talking points about generics that everyone has heard before, and which were made before this thread ever existed. What’s the point in repeating something that you could have said before the post you’re supposedly responding to ever existed? Your comment could have come out of a text generator.

          It’s one thing to point out an argument from authority when someone actually makes one, but it’s just as fallacious (if not more so) to make an argument from fallacy in response to someone not even being fallacious. The person you’re responding to didn’t say that Go was good because Rob Pike developed it, nor has anyone in the thread (as far as I’ve noticed, at least) said that Go shouldn’t have generics because Rob Pike said it shouldn’t. That would be an argument from authority, and fallacious.

          What is not an argument from authority is this: seeing people claiming someone is ignorant of computer science and pointing out that given their background they almost certainly are not. That’s not an argument from authority, or at least if it is, it’s justified being that the discussion is literally about whether they are an authority. ‘An authority said this is good so it is’ is an argument from authority. ‘Actually, you’re wrong, this person is an authority’ is not, especially when it’s in response to the indeed-fallacious ‘Go is bad because its authors aren’t educated in computer science’ which would be nonsensical as an argument even if it were true.

          The person you’re responding to simply said that people are picking on one minor issue and inflating it into a big flame war. Which you certainly are. ‘Well actually it isn’t minor’ isn’t a good argument for a start, but ‘Well actually it isn’t minor and you just think it is because you’re a Rob Pike fanboy’ is unbelievably awful.

          Until then it seems really weird for you guys to be insulting anyone who has these complaints as ivory tower complainers with no valid points.

          No, what seems weird is people that don’t use a language thinking that it should be designed to attract them instead of designed to work best for the people already using it. I think it’s a symptom of the modern age where everything is about market share and so people just assume that everyone wants them to be part of their market share. The mere idea that Go’s developers don’t care one iota about whether you like or use the language apparently hasn’t occurred to you.

          1. 0

            Thanks for your reply.

            Practically everything you say is negative in tone and dismissive of the person you’re replying to, and I have no interest in engaging you. Have a great day!

            1. [Comment from banned user removed]

      2. 3

        inflated into such a big flamewar like emacs vs vim.

        Emacs vs vim as a flame war is a joke. Maybe 20-30 years ago people seriously flamed each other about it, but I’ve personally never seen it in my time on the internet. I have seen 100x as many people talk about the ‘emacs vs vim flame war’ than I’ve seen actually participate in it, and even then all the participation in it is very clearly with tongue firmly placed in cheek.

        Go vs ‘reee no generics’, on the other hand, seems to be entirely serious.

    14. 12

      I may as well join in.

      I’ve had a light conversation with SirCmpwn before and he doesn’t care for macros either, which I find foolhardy, but I’ll focus on just this article.

      The inertia of “what I’m used to” comes to a violent stop when they try to use Go. People affected by this frustration interpret it as a problem with Go, that Go is missing some crucial feature - such as generics. But this lack of features is itself a feature, not a bug.

      I use a number of wildly different languages, including Common Lisp, APL, and most recently Ada; each of these languages is lacking things the other has, but it also vastly more suited to other tasks than the rest. I’ve never used Go. Unlike these three languages I’ve mentioned, which have perfectly good reasons for lacking whatever it is they lack, Go very often has poor reasons or perhaps even no reasons, although I don’t skulk around the mailing lists or whatnot.

      For a good example, take a look at this; it’s my understanding Go lacked a proper mechanism for determining time and many people critiqued this, but daddy Google didn’t care until someone important was hit by it. This is a good example of the problems caused by a language that is not only uncustomizable by the users, but is designed by people who don’t care and won’t care. Unless you’re someone, Google doesn’t care about what you think and the language certainly doesn’t, considering it is designed at every point to take away programmer choice.

      Go strikes me as one of the most conservative programming languages available today. It’s small and simple, and every detail is carefully thought out. There are very few dusty corners of Go - in large part because Go has fewer corners in general than most programming languages.

      This isn’t equivalent to a language that is good for writing programs in. Ofttimes, a lack of edge cases in the world of the language doesn’t correspond to a lack of edge cases in real use. Take a look at Ada for a counterexample; the rules may not have a nice technical explanation, but the corresponding real world explanation is very simple, because it’s usually to prevent some manner of error.

      I feel that this applies to generics. In my opinion, generics are an imperfect solution to an unsolved problem in computer science.

      Dynamic typing as in Lisp is one solution. Ada has a nice generic system, but again, Ada was designed not for theoretical prettiness, but to actually make large systems easier to write without flaws, so generics were of course there because otherwise you get people copying and pasting code, which makes maintenance and everything else harder because you can’t tell if one of the copies is wrong or otherwise changed easily or quickly.

      I used to sneer at the Go maintainers alongside everyone else whenever they’d punt on generics. With so many people pining after it, why haven’t they seen sense yet? How can they know better than all of these people?

      Have you ever considered these people don’t know better than anyone else. Have you considered that Go is just an extension of the UNIX and C religion and people like Rob Pike are just playing their part as a priest over scared people who don’t know any better and want a panacea and a movement to join?

      I don’t think programming languages should compete with each other in an attempt to become the perfect solution to every problem. This is impossible, and attempts will just create a messy kitchen sink that solves every problem poorly.

      I’d prefer to think that’s common sense. APL and its family is the clear choice for array problems, but will fall flat against many other types of problems. What is Go actually good for? I find that poor languages, typically ALGOL clones, tend to differentiate themselves on purpose rather than anything intrinsic. You see this with Perl being a ’‘scripting’’ language, Ruby being for ’‘web services’’, Python being ’‘glue code’’, and, what, Go being for ’‘scalable programs with a focus on internet-connected services’’? The key detail to observe is these languages are all rather the same and, utterly lacking originality, attempt to dominate in a particular usage, because that’s the only way they can really be differentiated.

      If you disagree with this, compare Perl to PHP to Go to Python and compare those differences to those between comparing Common Lisp to Forth to APL to Ada.

      If you’re fighting Go’s lack of generics trying to do something Your Way, you might want to step back and consider a solution to the problem which embraces the limitations of Go instead. Often when I do this the new solution is a much better design.

      I felt something similar when I was writing an Ada program and, wanting to use the package system properly, was forced to structure my program in a different, albeit natural and better way. Tell me if there’s a document that lists all of Go’s design decisions and why they were taken, or am I only going to find the typical UNIX and C response of ’‘We know better. It’s better this way. Don’t consider other ways. Our way is the one true way.’’?

      So it’s my hope that Go will hold out until the right solution presents itself, and it hasn’t yet. Rushing into it to appease the unwashed masses is a bad idea.

      Go was designed for the ’‘unwashed masses’’, I mean those ’‘not capable of understanding a brilliant language, but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.’’, straight from Rob Pike’s mouth. Go is designed to use programmers as unintelligent implementing machines, which is why it’s so opinionated. Its opinions have little or nothing to do with good programs and apparently everything to do with preventing the damage any single fool they want to use can cause or, worse, prevent a new hire who isn’t a fool from writing a good program that makes them more valuable than their peers and harder to fire. There’s no macros in Go, only the same thing, everywhere, no matter how poorly suited it is to the problem. If everyone writes Go the same, it’s easy to fire and interchange employees without friction.

      I could keep going on about how Go is just a continuation of UNIX, C, and so also Plan9, UTF-8, and whatever else those malign idiots create, but I believe this gets the point across well enough. The only ’‘philosophy’’ these things espouse is that the computer isn’t a tool for leveraging the mind.

      1. 10

        ’‘We know better. It’s better this way. Don’t consider other ways. Our way is the one true way.’’

        Hilariously, a pro-Go commenter just said to me that Go is an anti-“we know better” language.

        Go is just an extension of the UNIX and C religion

        And yet it goes against everything in the actual modern Unix world. Go likes static linking (because Linux distros), has custom syscall wrappers, a custom assembler (!), custom calling convention and weird stack setup… As a result, calling non-Go code requires either overhead (cgo) or ridiculous hacks (c2goasm), LD_PRELOAD hooks don’t work, and porting the main official Go implementation to a new OS/CPUarch combo is utter hell.

      2. 9

        Go being for ’‘scalable programs with a focus on internet-connected services’’?

        Two comments: the two wins go has over other languages is

        • (1) build/link - that its build system is fast, and it produces reasonably small static binaries, suitable for deploying into containers. This requires a fair bit of fiddling in other languages and with fairly large binaries in the outcome. Not infeasible, but certainly more than plug and play.

        • (2) it aligns with the sensibilities of python and ruby programmers in general, but in a typed manner, so improved maintainability with a fairly simple semantic.

        I’m not a go fan, but these are key good things for go.

        Rather write in something like Haskell or Common Lisp, but ce la vie…

      3. 9

        I had you until the last paragraph. What the heck do you find bad in UTF-8?

        1. 1

          I don’t want that to turn into its own discussion, but I have reasons aplenty and I’ll list all those that currently come to mind.

          Firstly, I have my own thoughts about machine text. I find the goal of Unicode, being able to have all languages in one character set, to be fundamentally misguided. It’s similar to the general UNIX attitude: ’‘Should we have the ability to support multiple standards and have rich facilities for doing so transparently? No, we should adopt a single, universal standard and solve the problem that way. The universal standard is the one true way and you’re holding back progress if you disagree!’’.

          Operating systems can support multiple newline conventions, as VMS did, and it would be trivial to have a format for incorporating multiple character sets into a single document without issue, but that’s not what is done. Instead, Unicode is forced and there are multiple Unicode encodings. Unicode is also filled with dead languages, emojis, and graphics-building characters, the latter being there, I think in part, because GUIs under UNIX are so poor and so turning the character set into the GUI toolkit is such an easy ’‘solution’’. I’m fully aware the other reasoning is likely to encompass graphics from other character sets, however.

          UTF-8 is a large, variable-length character set that can have parsing errors, which I find unacceptable. It’s backwards compatible with ASCII, which I also dislike, but at least ASCII has the advantage of being small. UTF-8 takes pains to avoid containing the zeroeth character, so as to avoid offending C’s delicate sensibilities, since C is similarly designed to not accommodate anything and expect everything to accommodate it instead. It is as if Ken Thompson thought: ’‘I haven’t done enough damage.’’

          UTF-8 disadvantages other languages, such as Japanese and Chinese (This isn’t even mentioning the Eastern character controversy.), by being larger than a single-minded encoding, leading several such peoples to prefer their own custom encodings, anyway. You can only add UTF-8 support to a program transparently in trivial cases, as anything more such as a text editor will break in subtle ways.

          There’s also that Unicode makes the distinction between characters, graphemes, and other such things that turn a simple problem into an unmanageable one. I use Common Lisp implementations that support Unicode characters, but don’t actually support Unicode, because there are so many combining characters and other such things that have no meaning to Common Lisp and so can’t be implemented ’‘correctly’’, as they would violate the semantics of the language.

          There are other reasons I can list, but this is sufficient.

          1. 10

            multiple standards and have rich facilities for doing so transparently

            Well, looks like getting everyone to agree on a way of selecting encodings turned out to be way harder than getting everyone to agree on one encoding :)

            And sure — we have Content-Type: what/ever;charset=MyAwesomeEncoding on the web, we can have file formats with specified encodings inside, but there’s nothing you can do about something as fundamental as plain text files. You could never get everyone to agree to use something like extended FS attributes for this, and to make it work when moving a file across filesystems… that’s just not happening.

            format for incorporating multiple character sets into a single document without issue

            Again, some format that software has to agree on. Plain, zero-metadata text fields and files are a thing that’s not going away, as much as you’d like it to.

            UTF-8 disadvantages other languages, such as Japanese and Chinese

            They often include ASCII pieces like HTML tags, brand names, whatever; you should use an actual compressor if you care about the size so much; and every character in these languages conveys more information than a Latin/Greek/Cyrillic/etc character anyway.

          2. 8

            It seems like you don’t actually know what UTF-8 is. UTF-8 is not Unicode. Rob Pike did not design Unicode, or have anything really do to with Unicode. Those guys designed UTF-8, which is an encoding for Unicode, and it’s an encoding that has many wonderful properties.

            One of those properties is backwards compatibility. It’s compatible with ASCII. You ‘dislike’ this, apparently. Why? It’s one of the most important features of UTF-8! It’s why UTF-8 has been adopted into network protocols and operating systems seamlessly and UTF-16 hasn’t.

            UTF-8 doesn’t ‘disadvantage’ other languages either. It doesn’t ‘disadvantage’ Japanese or Chinese at all. Most web pages with Japanese and Chinese text are smaller in UTF-8 than UTF-16, despite the actual Japanese and Chinese text taking up 3 bytes instead of 2, because all the other bytes (metadata, tags, etc.) are smaller.

            The fact is that anyone that says that Unicode ‘makes the distinction between characters, graphemes, and other such things that turn a simple problem into an unmanageable one’ doesn’t know what they’re talking about. Unicode did not create those problems, Unicode simply represents that problem. That problem exists regardless of the encoding. Code units, code points, characters, graphemes.. they’re all inherently different things.

            Unicode does not have any GUI characters.

          3. 2

            Could you maybe elaborate the following quote?

            UTF-8 disadvantages other languages, such as Japanese and Chinese (This isn’t even mentioning the Eastern character controversy.)

            1. 7

              I reckon it refers to the controversial Han unification, which was in China’s favour.

          4. 1

            It’s similar to the general UNIX attitude: ’‘Should we have the ability to support multiple standards and have rich facilities for doing so transparently? No, we should adopt a single, universal standard and solve the problem that way. The universal standard is the one true way and you’re holding back progress if you disagree!’’.

            What precisely does UNIX force you into? Are you sure this isn’t also the LISP attitude as well? For example, Lispers usually sternly glare over the interwebs if you dare you use anything but EMACS and SLIME.

            Operating systems can support multiple newline conventions, as VMS did, and it would be trivial to have a format for incorporating multiple character sets into a single document without issue, but that’s not what is done.

            You’re confusing multiple newlines in a single character encoding with multiple newlines across character encodings. You say that it would be trivial to have multiple character sets in a single document, but you clearly have not tried your hand at the problem, or you would know it to be false.

            Give me twenty individual sequences of bytes that are all ‘invalid’ in twenty different character encodings, and then give me 200 individual sequences of bytes that are all ‘invalid’ in 200 different character encodings. Otherwise there is ambiguity on how to interpret the text and what encoding is used.

            This problem can be seen by the people who are trying to revamp the c2 wiki. Reworking it has stalled because there are around 150 files with multiple different character encodings, and they cannot be identified, separated, and unified by the machine.

            Unicode is also filled with dead languages, […]

            Right, because Unicode is supposed to be a superset of all encodings. The fact it supports languages that are not used anymore is a feature, not a bug. It is important to people working in linguistics (you know, that field outside of computer science…) that any computer encoding format has a method of displaying the text that they are working with. This is important to language archival efforts.

            UTF-8 disadvantages other languages, such as Japanese and Chinese (This isn’t even mentioning the Eastern character controversy.

            This is outright false, but someone else has already mentioned that.

            I use Common Lisp implementations that support Unicode characters, but don’t actually support Unicode, because there are so many combining characters and other such things that have no meaning to Common Lisp and so can’t be implemented ’‘correctly’’, as they would violate the semantics of the language.

            Unicode allows language implementations to disallow some sets of characters for ‘security’ reasons: http://www.unicode.org/reports/tr31/

            This entire rant remined me of Steve Yegge’s post “Lisp is not an acceptable Lisp”:

            But what’s wrong with Common Lisp? Do I really need to say it? Every single non-standard extension, everything not in the spec, is “wrong” with Common Lisp. This includes any support for threads, filesystem access, processes and IPC, operating system interoperability, a GUI, Unicode, and the long list of other features missing from the latest hyperspec.

            Effectively, everything that can’t be solved from within Lisp is a target. Lisp is really powerful, sure, but some features can only be effective if they’re handled by the implementation.

      4. [Comment from banned user removed]

        1. -5

          He’s just a butthurt Lisper who’s mad his elegant, beautiful language is ignored by people who actually get stuff done. UNIX-haters and that.

    15. 10

      Just wow. I can read a lot of things with a straight face, but the liberal use “no true Scotsman” combined with copious amounts of fanboyism really made me cringe hard.

      Maybe it’s time to remind people that the things they put on the Internet are there forever and might cause embarrassment to their children and grand-children, especially articles like these.

      Articles like these make me lose my hope that software development will ever rise above alchemy, superstition and wishful thinking during my lifetime.

      1. 24

        Agreed, you can substitute the name of some other programming language, and the content doesn’t really change.

        The constraints imposed by the lack of generics (and other things FORTH lacks) breed creativity. If you’re fighting FORTH’s lack of generics trying to do something Your Way, you might want to step back and consider a solution to the problem which embraces the limitations of FORTH instead. Often when I do this the new solution is a much better design.

        I try to hold myself to “if I’m going to complain, show examples of how to do better” so here we go.

        I would prefer to see content like “Here’s a problem commonly solved with generics, and here’s one way to implement that same thing in Go”.

        I would like to point out that Go does have generics for two three of the system types, list and array and map. One way to sort-of get generics is to wrap those system types inside whatever data structure you actually wanted to build. That is, you can build a generic tree datatype, but under the covers it’s actually some combination of list and array, and you still sort-of get the behavior of generics in other languages. To get more generic type signatures, you can declare types as “empty interface” which is roughly the “superclass of all values” and then most things will work. You will still have runtime errors if you try to cast a value from the “any” type to a type that doesn’t match, so you have to be very careful.

        I guess a more thorough response would include code demonstrating the above, but I’m busy writing Python today. Does anyone already have handy examples of the above solutions?

        (Bias statement: my favorite language is Haskell!)

        (edited to add maps to the list of generic system types)

        1. 14

          Problem: implement a custom container data structure.

          Solution:

          “empty interface” which is roughly the “superclass of all values”

          Conclusion: why have a static type system at all if you can’t even use it for typechecking the use of your container? :)

          One way to sort-of get generics is to wrap those system types inside whatever data structure you actually wanted to build. That is, you can build a generic tree datatype, but under the covers it’s actually some combination of list and array, and you still sort-of get the behavior of generics in other languages

          I’m not sure I understand. If you wanted to define a FancyThing<T> that consists of List<T> and Map<int, T>, you’d still need actual generics support to parameterize FancyThing and pass these types into the members’ types. Otherwise you can only instantiate the builtins with interface{}.

          1. 7

            Problem: implement a custom container data structure.

            “Implement a custom container data structure” is never your problem. Problems are more like “serve web pages to users” or “crunch data from this database”.

            1. 25

              Yes, if you’re an application author, you have these problems, and Go is 100% made for you.

              If you’re a library author, “implement a data structure” is your problem, and Go suuuucks for you.

              1. 7

                I don’t think that Go is really oriented towards writing libraries rather than writing applications. Sure, lots of people write libraries in Go (I have!), but the language itself feels like it’s meant to be used rather than abstracted with. That’s okay, I think.

              2. 5

                Yes, it does. Remember the part where I said I’m okay with certain classes of problems being off the table?

                1. 13

                  “I need a data structure for my application that is flexible enough for different frobz and widgets that has faster amortized access than go’s map, but I have to duplicate the code because the author of a red black tree library can’t do their job generically and safely.”

                  1. 0

                    Go has a way to do this called go generate. It adds an extra step to builds which is an ergonomic downside but on the other hand it doesn’t suffer from type erasure and the debugging messages are way way better than C++ templates.

                    The author of your red black tree library can absolutely do their job generically and safely. They just don’t want to.

                    1. -1

                      Go generate is a way to invoke an external generator, isn’t it? So you’d have to make a generator that’s essentially a “TypeScript for Go”. TypeGo. LOL.

                      1. 4

                        First, go generate is intended§ to be run by the author of a package, not the client of it. The author of the package generates the required Go files and includes them in the package; the client does a regular go get or go build. Generation through go generate is not part of the build, just a tool for package authors. This avoids complicating the dependency analysis done by Go build.

                        https://docs.google.com/document/d/1V03LUfjSADDooDMhe-_K59EgpTEm3V8uvQRuNMAEnjg/mobilebasic

                        (In other words, an RB tree distributed like this is not intended usage)

                        Also, plot twist: nothing forces a script run by go generate to actually generate anything.

                2. 7

                  What an incredibly user-hostile attitude. You’re okay with penalizing library authors, precisely the people that contribute most to the community?

                  1. 4

                    A library-author-hostile attitude, you mean. And this is only a particular kind of library, e.g. the ones which implement some kind of generic data type. Many libraries don’t need to do this, and get by fine with just interfaces. It’s similar to the situation in C: everyone just implements their own data structures and that’s fine.

                  2. [Comment from banned user removed]

            2. 5

              “Implement a custom container data structure” is never your problem.

              I forget that gophers have such a crippled type system that they say stuff like this. In a sensible language such as Haskell, one might have

              data Day = Monday | Tuesday | ... | Sunday
              
              type Schedule = Map Day [String]
              

              Just because Go’s type system has so few interesting features that you don’t want to ever implement a custom container, doesn’t mean that’s the case for everyone.

              1. 3

                Quality snark!

                The limits of my language are the limits of my world

                1. [Comment from banned user removed]

              2. 1
                type Day interface{}
                type Monday Day
                type Tuesday Day
                type Wednesday Day
                // ...
                type Sunday Day
                type Schedule map[Day]string
                
                1. 11
                          s := Schedule{}
                  	var k interface{}
                  	s[k] = "zoink"
                  	var j Saturday
                  	fmt.Println(s[j])
                  

                  What a safe way to write programs in 2019! All those silly academics with their type safety nonsense!

              3. [Comment from banned user removed]

          2. 3

            You can cast the empty interface to a specific type at runtime, in the case that the code calling your FancyThing decided to choose the types you’re using. In my employer’s codebase I’ve seen lists and arrays of interface{} where the it’s expected that code using FancyThing will check the types before use.

            Go lang takes the Samurai Principle too far for my tastes, the cultural approach to runtime errors (the way I understand it) is that the program should immediately die. To me this implies that runtime errors should not be allowed outside of truly exceptional circumstances where the program cannot possibly continue. My take on that is, “don’t do runtime casting of any sort” so that kinda kills the idea of using the empty interface.

            I could easily be wrong, I’m certainly not an expert on idiomatic use of Go, though I have spent the last year or two working on a 50k line codebase for my employer. I would appreciate input/feedback from anyone with more understanding of idiomatic use of “die for any error” and “runtime casting of empty interface”.

            1. 4

              die for any error

              Huh? I remember that there’s a lot of passing errors around. But of course in an obnoxious explicit fashion:

              something, err := maybeDoSomething(x)
              if err != nil {
                return nil, err
              }
              

              And every call looks like this. So much simpler than Result/Either :D

              1. 0

                For many cases, you can do this, though:

                if err := x.doSomething(); err != nil {
                    return fmt.Errorf("error when calling x.doSomething: %v", err)
                }
                
                1. 6

                  OK, so it’s slightly more compact… that doesn’t fix the underlying problem though.

                2. 3

                  That looks really side-effecty, as it doesn’t capture a return value :-) I personally find that even when my program is about ‘doing’ rather than computing, I still have a lot of pure functions in my program because I need to manipulate data before I can act on it – how is that in your experience? (Probably different! I expect we have different styles as well as domains!)

          3. -1

            Problem: implement a custom container data structure.

            That’s a problem almost nobody actually has, but ok. You could use code generation, which would give you the typechecks you were looking for. Don’t some “real generics” implementations essentially do this also?

            1. 6

              Surprisingly, I had this problem last week, I really needed a suffix (or prefix) tree that would return the count and value of keys that match a particular suffix. I ended up using strings.HasSuffix instead, but it’s going to make future maintainers sad when they read that code.

              1. -6

                YAGNI

            2. 4

              That’s a problem almost nobody actually has, but ok. You could use code generation, which would give you the typechecks you were looking for.

              Plenty of people have this problem. Perhaps the reason people don’t do it more in Go has more to do with the fact that the type system is too weak to handle even simple algebraic sum types, so you just use e.g. integers to express what should be something else.

              Don’t some “real generics” implementations essentially do this also?

              Not really, at least during typechecking.

        2. 2

          Forth doesn’t lack generics - it just doesn’t have types…

        3. 1

          After a few minutes searching, I found an article that’s much better than anything I could say about generics in Go: https://appliedgo.net/generics/

          I completely forgot that Go interfaces are pretty much like Java interfaces (what I think of as typeclasses).

          I will also point out that option 6 in the article I linked is exactly the C++ approach, use code generation to build a type-specific implementation at compile time.

          I’ve not used reflection in Go, so no opinions here.

        4. 1

          I think you mean map & slice.

          1. 1

            From what I’ve read, arrays and slices are both generic, but slices are a reference-oriented layer on top of arrays. To me arrays and slices are pretty much different views/parts of the same data structure, what do you think?

            The slice type is an abstraction built on top of Go’s array type, and so to understand slices we must first understand arrays.

            That’s from this 2011 blog post: https://blog.golang.org/go-slices-usage-and-internals but it’s not 2011 anymore.

            1. 9

              Slices, arrays, channels, pointers and maps all support some limited form of polymorphic type-safe operations on them.

              This discussion is a complete pit. I suggest you bow out while you can. Hell, this sub-thread’s parent comment is literally calling for the OP to be shamed by our descendants based simply on an opinion expressed about a programming language. The fact that nobody has called @soc out of this yet (ah, someone just did, yay) just shows how much all of us have been numbed to how ridiculous this conversation has gotten. The other side is almost as ridiculous too. Apparently implementing type safe reusable data structures isn’t actually a solution to anything.

            2. 2

              Yes, arrays are generic; it’s that they’re not used much in practice becuase slices are much more convenient. My main point was that you left out maps.

              1. 1

                Oh, good point! I’ll fix that!

        5. [Comment from banned user removed]

      2. 18

        Your patronizing tone isn’t really contributing to the discussion.

      3. [Comment removed by moderator pushcx: Don't tell people to leave the site. Removing this subthead.]

        1. [Comment removed by moderator pushcx: Removing this subthread. Let mods mod.]

          1. [Comment removed by moderator pushcx: Removing this subthread. Let mods mod.]

          2. [Comment removed by moderator pushcx: Removing this subthread. Let mods mod.]

      4. [Comment removed by moderator pushcx: Removing off-topic troll. Please don't pour gas on a fire.]

    16. 6

      So here’s the gist of it: “I feel that this applies to generics. In my opinion, generics are an imperfect solution to an unsolved problem in computer science.”

      I wholeheartedly agree with that opinion. In fact, I feel that the list of PL design things that are solved in computer science is rather small. Everyone just has tons of opinions, sometimes very angry ones, but nobody has proof or even evidence – or the few times they do, it’s all rather inconclusive and seems almost random. For instance: https://cacm.acm.org/magazines/2017/10/221326-a-large-scale-study-of-programming-languages-and-code-quality-in-github/abstract

      1. 16

        What exactly is the unsolved part? Generics are one way of abstracting and reasoning about algorithms/programs that preserve certain structural properties. They’re not the silver bullet that solve all logic bugs and they’re not any more overhead than unit tests.

        I really wish people that have opinions on generics would spend some time reading the relevant literature to understand the logical underpinnings of generics and using languages that support them instead of picking a side in an unnecessary flamewar.

        1. 7

          Yes, it would be good if folks did more reading, not just on understanding why generics are good, but why they can be bad. Here are some links:

          Anyone who tries to bin generics as some sort of simple solved problem that was figured out decades ago clearly hasn’t given much thought to it. The downsides are very real. Even in Rust, which has a reasonably sophisticated type system, generics are a significant source of both problems and solutions. Sometimes they are overused and make APIs more complicated than they need to be. More practically, they are a contributing factor to the long compile times in the Rust ecosystem. This is an extraordinarily hard and delicate trade off to balance.

          1. 0

            Is sorting also not a solved problem because there are variations with different tradeoffs? Are the folks in the go ecosystem waiting for breakthrough research that will give them the best possible implementation of generics?

            It’s hard to make sense of the counter-argument with quotes like

            Generic structures tend to accumulate features from all uses, resulting in increased compile times or code bloat or needing a smarter linker. – Summary of Go generics discussions

            1. 6

              Sorting is hard and choosing the right algorithm isn’t always obvious. The quote about generic structures accumulating features is absolutely true in my experience. The scales between sorting algorithm choice and language defining features like generics are vastly different, so I’m not sure it’s productive to get hung up on verbiage like “not a solved problem.” Like, what do you want me to say? Why does a position on sorting have to carry over to generics? Why does “not a solved problem” need to have such a narrow definition? The links I provided should more than clarify the trade offs and design constraints in play.

              My point is that both sides—at least the vocal parts represented in this thread—are woefully uneducated on the position they’re arguing against. So your advice to read more is great. But reading more doesn’t just entail reading about arguments in favor. We should also read and learn about opposing arguments. Why are you arguing with me about this? Are you really going to say we shouldn’t try to understand the opposing position better?

              Here’s an even better mental exercise. Forget just reading about the opposing position. Try arguing in favor for it, even if you find it ridiculous. If you can’t come up with a reasonable argument in good faith that represents your opponent’s position, then perhaps there’s something else wrong, and we should focus on fixing that first. Because if you can’t articulate the opponent’s argument, then there’s no point in arguing about this at all.

              1. 0

                When I said it’s hard to make sense of the counter arguments I wasn’t making an abstract claim. The justifications given against generics seem to be non-sequiturs. What logical implication follows from “Generic structures tend to accumulate features…”. Help me understand why this is a valid argument against generics. If I reason by analogy then I’d conclude that gophers are against calling conventions and functions as well but clearly they use functions with all the overheads they entail without worries. The delineation of simplicity seems arbitrary to me and whenever an arbitrary technical line is drawn then experience tells me it is a social problem and unrelated to any technical merits or demerits.

                1. 7

                  You can’t reason by strict logical implication because language design isn’t the result of cold logical conclusions. It’s always about balancing costs with benefits and squaring that with design goals. A language is, at least in part, a communication tool and the features of that language strongly guide how one expresses themselves in the source code. If a language feature like functions can lead to bad things, then it can also certainly lead to good things. The same is true for generics. Does the good outweigh the bad? Well, to answer that question you have to ask what your design objectives are. Functions are a fundamental unit of decomposition in a program, and without them, it’s pretty hard to be productive. Their costs are nothing compared to the general benefits they convey. Generics also have a host of technical merits and demerits, and those are covered in great detail in the links I gave. Which merits and demerits you care about and how much weight you attach to each depends heavily on your design goals. It’s completely sensible that if both compilation time and execution time is critically important to you, then the technical merits and demerits of generics are directly related.

                  I’ve thought about this a lot, and I just truly don’t understand why this is so difficult for folks to understand. There’s a wide range of very specific technical details (again, laid out in the links I gave) that are relevant here. The only difference is the value system that assigns weights to how much one cares about each technical detail. For example, if your experience has led you to believe that bloat in software is a problem, then you might very well believe that crafting language features that reduce the tendency to add bloat is A Good Thing. There are many contributors to bloat, but it’s not unreasonable to see why someone might think that generics is one of them. That’s a clear line of reasoning that assigns a negative value to generics, but that doesn’t mean it’s some kind of strict logical deduction that’s universally true. It’s heavily dependent on how much weight you attach to things like “bloat in software is bad” or “we can tolerate because we have other things that counter act the impact of generics on bloat” or “generics is undoubtedly useful, but not as useful as conventional wisdom would hold” or “generics is useful and necessary, but maybe there is an 80/20 rule in place here where some generics gets a lot of the way there.”

                  1. 4

                    Your back-and-forth here reminded me of the book After Virtue by Alasdair MacIntyre. Maybe programming languages, as much as they are technical or grammatical artifacts, are also “communities of practice” or “traditions” as MacIntyre calls them. He thinks we’ve lost the understanding of virtue as excellence within a tradition, and that our contemporary moral debates are “interminable” and “shrill” for this reason.

                    1. 1

                      Interesting. I did some research on the book since I hadn’t heard of it before. While I’m skeptical of several aspects of it, it does pique my interest. I’ve added it to my reading list. Thanks!

                      1. 2

                        It’s well written and (as far as I know) quite significant, so definitely worth reading! A philosophical encyclopedia’s article about MacIntyre is another option of course.

        2. 0

          I really wish people that have opinions on generics would spend some time reading the relevant literature

          Why would you assume that I haven’t? Because I disagree with your opinion?

      2. 7

        I wish the author had spent more time discussing what generics do and do not solve, just so I can understand where this part of his argument came from.

    17. 3

      The “empty interface every data structure” approach in Go really just makes it feel more like Javascript than anything to me. It’s really funny to think about. “We pride ourselves on being simple. Also to make any sort of data structure you must do arbitrary typecasting!”