Go: Don't Change the Libraries in 1.18

183 points by dbattaglia 3 years ago | 122 comments
  • nine_k 3 years ago
    A good call, and probably the most reasonable decision in their situation.

    OTOH this removes much of the point to use generics, and makes working with stdlib from type-parametric code more painful.

    Still great to see things improving. It took mere 11 years.

    • verdverm 3 years ago
      There is a path to upgrading library functions to generics, it will come in a later release. Looked like default generic type of the empty interface for those functions. See the other issues linked from the original.
      • tonetheman 3 years ago
        It took that long because you do not NEED generics.
        • colejohnson66 3 years ago
          Well, no language ever needs features. We could all write software in C or even assembly, but we don’t because abstractions are nice. Generics are an abstraction.

          Take C# for example. The `System.Collections.Generic` namespace is full of generic collections (surprise!) that allow more type safe code. If I have a `List`, I can’t guarantee there isn’t something I don’t want in there (that could cause a runtime exception I don’t catch). But if I have a `List<IFeature>`, I know that everything in the list implements `IFeature` (barring compiler bugs and unsafe code).

          • closeparen 3 years ago
            To be fair, Go has typed maps and slices. You just can’t implement your own generic collections, or generic operations over collections. Those two will get you decently far.
            • grey-area 3 years ago
              Abstractions are not always nice.

              One of the nice things about go is it doesn’t have many abstractions and most of them are carefully thought out. I don’t want to have to inhabit somebody else’s abstractions all day at work, I want the language to get out of the way, which go does quite well IMO.

          • throw_m239339 3 years ago
            > Still great to see things improving. It took mere 11 years.

            Took that much time because of little clique of people outside the go team had way too much influence in the Go community. Let see if they dump the language like they threatened to, as the result of adding generics. Of course they won't.

            Generics are there if one wants to, and they aren't like Java, but ADA. ADA got a lot of things right decades ago including the way tasks work from which Go routines should have taken a bit more inspiration .

            Congrats to the Go time anyhow.

            • stevekemp 3 years ago
              I suspect a lot of people outside the go-team made comments, suggestions, and proposals. But honestly, thinking back damn few of them resulted in changes to the language.

              If you'll recall back in the day there were several different vendoring approaches, but ultimately the go-team proposed and implemented their preferred solution.

              Similarly there have been a million generics & error-handling suggestions but none of them were introduced. It's basically lots of distracting discussions, and it doesn't feel so much like a community project that is actually seeking outside discussion and ideas. (No shame in that, but the pretense is disappointing).

              Personally I'm waiting for the fuzzing-support to land in 1.18. Fuzz testing is basically magical, and amazing in reporting problems even in code with "high coverage". The generics might be nice, but off-hand I don't see that I'll be needing them in the immediate future in any of my personal projects - but I fuzz-test the hell out of a lot of my projects (which largely revolve around interpreters and compilers).

              • gnfargbl 3 years ago
                I actually think this is one of the reasons I like go so much, and now write code in it almost exclusively -- it isn't really a community project, but rather a labour of love from a small number of genuine experts.

                If it actually were a community project, I think we would have more of the "x := make(someType) vs. x := someType{}" TMTOWTDI that you find in other mature languages, and go would be weaker for it.

                • ithkuil 3 years ago
                  Those community efforts may have not been have adopted, but that doesn't mean their existence hasn't informed the Go team's solution
                • nine_k 3 years ago
                  I can only repeat the top comment from the "8 years of Go" thread [1]: the team made a different set of priorities, and was hugely successful in implemneting them, which also brought a ton of popularity. Golang is not my cup of tea, but I very much see the large and underserved niche it filled.

                  [1]: https://news.ycombinator.com/item?id=15671676

                  • kubb 3 years ago
                    Rob was opposing generics from the start. People were pointing out the need more than a decade ago, but he was firmly saying no. Now he left the team.
                    • mseepgood 3 years ago
                      > Rob was opposing generics from the start.

                      That's simply not true.

                      > he was firmly saying no.

                      I'm sure you cannot find a single instance where he firmly says no to generics.

                      He wrote in the FAQ that Go might get generics one day and that they are continuing to think about it.

                      Here he is arguing in favor of generics: https://www.reddit.com/r/golang/comments/jditu9/what_do_gene...

                      And he was the one who invited Phil Wadler to help with the generics design. From the Featherweight Go paper: "Rob Pike wrote Wadler to ask: Would you be interested in helping us get polymorphism right (and/or figuring out what “right” means) for some future version of Go?" https://arxiv.org/pdf/2005.11710.pdf

                      • 1_player 3 years ago
                        He's left the team? He seems pretty active even in this recent github thread.
                        • 3 years ago
                        • cerved 3 years ago
                          Go doesn't/didn't have generics? Why?
                          • lifthrasiir 3 years ago
                            It was commonly stated (or claimed) that they didn't know how to add generics without sacrificing both compilation time and runtime performance [1]. To my knowledge they ultimately didn't choose a particular implementation strategy and instead chose a design that allows multiple strategies as needed.

                            [1] https://research.swtch.com/generic

                            • jikbd 3 years ago
                              Because features in software don’t exist until someone adds them.
                        • kubb 3 years ago
                          What will likely happen is that the users will design generic libraries themselves. There will likely be a couple, and eventually they will converge on the most useful features. Then the Go team can just get inspiration from that I guess.

                          I'm excited about the prospect of having iterators. It will enable a different, more consistent programming style.

                          I'm also hoping for immutable collections, even though the lack of specialization will make it more difficult to implement them efficiently. They would enable a more robust way to build concurrent systems.

                          • chrsig 3 years ago
                            > What will likely happen is that the users will design generic libraries themselves. There will likely be a couple, and eventually they will converge on the most useful features. Then the Go team can just get inspiration from that I guess.

                            Most likely yes, or as stated in the ticket, they'll take the existing proposal and implement it in golang.org/x/, where they've had some success fleshing out the design of new packages before incorporating into the standard library. It's worked out well, as early adopters can adopt and generally have a painless transition once included in the standard library.

                            I agree with iterators and immutable collections -- it's been painful working with trees in go, so hopefully that gets a bit easier now.

                            Honestly, I'm excited to see what will come of generic functions for channels. Being able to write a generic Dup(in chan T, out ...chan T), or a CtxRecv(context.Context, chan T) (T, error) to cut down on some boilerplate select statement.

                            • kubb 3 years ago
                              +1 for channels, a simple task like duplicating a channel is surprisingly tricky, verbose and error prone
                            • cy_hauser 3 years ago
                              Or, if history is a guide, there will be a few really nice generic libraries written and a sizable minority of developers will adopt them as pseudo standard to fill the void. Then the Go team will do what they want, fracture the community, and alienate those who expected your described path to be the one taken.
                              • chrsig 3 years ago
                                I think they've been worse about this w.r.t. tooling (dep comes to mind. The closest thing I can think of along this path for the standard library would be how they've handled errors, and deciding to go their own way instead of adopting dave cheney's pkg/errors[0]

                                they do definitely seem to have some NIH syndrome at times, but I can't say that as time has progressed that I haven't come to appreciate the decisions they've made that seemed controversial at the time.

                                [0] https://github.com/pkg/errors

                            • IceWreck 3 years ago
                              > What will likely happen is that the users will design generic libraries themselves

                              the Go team has already made the libraries, theyre just publishing them in the /x/ namespace instead of the stdlib.

                              /x/ has everything that's not under the Go compatibility promise, among other things from the Go project.

                            • dathinab 3 years ago
                              Hm, shouldn't they first update the (most important/interesting) libraries in a fork before stabilizing generics?

                              I mean designing a feature in a clean room is one think, but using it a the standard library would be a good way to know if they messed up the design in some way.

                              • spockz 3 years ago
                                Yes that would be a good idea. However, they could already have a generic collection lib in the same place (branch/repo) where the generics feature is created.
                                • lbhdc 3 years ago
                                  This is what Rob proposes in this issue.

                                  > I propose we still design, build, test, and use new libraries for slices, maps, channels, and so on, but start by putting them in the golang/x/exp repository.

                              • cube2222 3 years ago
                                Also think this is a good call.

                                Though the second comment has merit too, I think it would be good to have some common abstraction right away, like we had io.Writer, io.Reader, etc. so everybody doesn't define their own, as it'll take time to crawl out of that.

                                Although in practice it did work out well with error wrapping which was first in libraries and then the stdlib defined an interface for them, which resulted in all libraries adopting that.

                                > Similarly, if constraints isn’t part of 1.18, there will be a lot of independent redefinitions of orderable types. I don’t think we’re going to learn from experience much that could change that package now.

                                • 1_player 3 years ago
                                  tl;dr: We're shipping generics in 1.18, it's a huge release so let's wait a little bit until they stabilise and they're used in production before changing our stdlib.

                                  Good call in my book, and I'm extremely excited to have generics finally. I thought they were going to ship with 2.0, but the sooner the better!

                                  It's cool to hate on Go, it's taken over the system programming space for a reason, like it or not, and after working full time on Elixir it's hard not to think in map/reduce and other generic constructs, which were unreasonably verbose before in Go. Now the haters will have to focus on the "if err != nil" statement to pile on the language — though to be fair I'll expect some ergonomic improvement on that aspect as well, eventually.

                                  With generics, Go will be my new Python, but with a decent dependency and deployment story, and I'll just need Zig for my low-level manual memory management needs. What's Rust?

                                  EDIT: indeed being a bit cheeky with HN's favourite language isn't well received in this place.

                                  • throw_m239339 3 years ago
                                    > It's cool to hate on Go,

                                    criticism =/= hate

                                    Nobody "hates" on Go for the sake of it. If some people were not critical of that language, generics would have never been added at first place. I'm glad the Go team acknowledged the flaw instead of the gaslighting that has been going on for years in the go community from a few go users.

                                    • 1_player 3 years ago
                                      Calling it "gaslighting" is exactly what a hater would do. It's not very constructive.

                                      Generics were a pain point, but people have been crapping on Go on this forum while people out there are using it to build stuff. It's not a perfect language, but if you read any HN thread about it it's like it's impossible for people to go past the lack of generics or the existence of nil.

                                      • sanderjd 3 years ago
                                        It is a good use of the word "gaslighting", which I think can be defined as "an effort to convince someone that they do not know a thing that they do know". In this case, a lot of people know from lots of experience that writing type safe generic code is extremely useful, but the go community spent a long time arguing that people could not have had that experience because writing generic code isn't actually useful. This isn't really my impression of what the go team was saying, which I interpreted as more like "parametric polymorphism is useful but we aren't sure it is a good fit with the simple language design we are seeking to maintain". That's totally reasonable, everything is trade offs, but that's not the prevailing pushback you would get from the go community, you'd instead hear a message more like "if you'd rather write generic code instead of copy pasting constantly, you're a bad programmer who doesn't get it", which is not helpful and yes, I think gaslighting is a reasonable description.

                                        The existence of nil is also a design flaw. But you're right that no language is perfect and neither of these flaws keeps people from building tons of useful stuff with the language.

                                        I think there is definitely gaslighting in the other direction too, which is what you're highlighting: lots of people know from experience that go is a super useful language, but then people come of as saying "your experience does not exist, it is not a useful language because of these big design flaws".

                                        • pjmlp 3 years ago
                                          I started coding in 1986, naturally I used plenty of languages without generics to build stuff, that doesn't mean it still makes sense in the 21st century to design strongly typed programming languages without generics.
                                          • djur 3 years ago
                                            Some people crapping on Go in this forum are also people who have been using it to build stuff, though. It's inaccurate to assume these are distinct groups.
                                        • the_duke 3 years ago
                                          > it's taken over the system programming space for a reason

                                          I'm curious what you define as systems programming, because Go certainly isn't a systems programming language by the classic definition.

                                          Go has a complicated runtime and GC. It's really not in the same category as C/C++/Rust, but more like Java/C# , just without a JIT.

                                          The only domain where Go is a go-to language is the Kubernetes ecosystem. It's also decently popular for networking heavy applications / microservices / server applications, because the runtime is well suited for those domains.

                                          • Zababa 3 years ago
                                            Go is basically a systems programming language if you consider """the cloud""" a system, a big part of the ecosystem is built on it. It is basically between C/C++/Rust and Java/C#, which is "good enough".
                                            • fsociety 3 years ago
                                              In that case JavaScript is a systems programming language if you consider the web a system.

                                              Golang having GC and a heavy runtime make it unsuitable for systems programming IMO.

                                            • vips7L 3 years ago
                                              We’ll soon have Java and C# without a JIT once they are done working on their AOT compilers.

                                              The C# one seems to be further along though due to having supported the Mono/Xamarin AOT runtime for a long time and is really easy to setup, it’s just a package reference in your .csproj. It also has the benefit of coming with a modern usable language.

                                            • cageface 3 years ago
                                              Lack of null safety is still a major shortcoming in my book compared to Rust/Swift/Typescript.
                                              • another_Hans_M 3 years ago
                                                I never had a real issues with null safety in 3 years of using Go regularly. Maybe due to may long experience with Java which might have sharpened my eyes for null safety.

                                                Lack of enums and pattern matching is IMO the bigger issue. I miss that regularly.

                                                • everybodyknows 3 years ago
                                                  null safety: Can you provide us a reference to a working definition of the term?
                                                  • cageface 3 years ago
                                                    For example in Typescript, you can specify whether a parameter is allowed to be null in the signature of a function. If you do the compiler will make sure that you don't accidentally pass a null value to that function.

                                                      function foo(x: number) {
                                                        return x + 1;
                                                      }
                                                    
                                                      let y = null;
                                                      foo(y); // compiler will flag this
                                                    • Macha 3 years ago
                                                      null/nil can only occur in scoped use cases (Option<Foo>, Foo | null, Foo?) and so the compiler can warn you when something could be missing and you don't handle it without being incredibly noisy.
                                                  • EdwardDiego 3 years ago
                                                    At least now we can write a generic set that supports all the things you want a set to do, instead of using map[T]interface{} and a lot of for loops.
                                                    • everybodyknows 3 years ago
                                                      >map[T]interface{}

                                                      If the semantics desired are merely those of a simple set, why instantiate storage for the value side of the map? An interface{} consumes 16 bytes. Instantiating a struct{}, i.e. with no fields inside, consumes 0 bytes.

                                                      • EdwardDiego 3 years ago
                                                        Ah yeah, that's right, it was map[T]struct{} - it's been a bit since I had to do it.

                                                        I knew it was something with curly brackets instead of the map[T]bool I started using.

                                                        • Shish2k 3 years ago
                                                          Because when a language doesn’t supply common features out of the box, users implement them for themselves, and inevitably a lot of them do a bad job of it :)
                                                          • vips7L 3 years ago
                                                            More reasons to have a generic Set type in the standard library. That way you know the implementation is correct every time.
                                                        • pjmlp 3 years ago
                                                          Go has taken over kuberbetes related stuff, that is all.

                                                          Although I like it being used for systems programming stuff like TinyGo on embedded or F-Secure TamaGo unikernel, that is hardly taking over the domain where C and C++ still rule, and will keep to do so for decades to come, despite the increasing usage of Rust on the domain.

                                                          • stjohnswarts 3 years ago
                                                            That's because you can put out there why you like a language and people will upvote you. Dump on other people's choice in a systems language and you will likely suffer some down votes. Cheeky has a price.
                                                            • paedubucher 3 years ago
                                                              Brad Fitzpatrick stated in one of his talks, that a version of Go coming with generics will be called 2.0 eventually. Maybe they do the version jump if there are backward-incompatible changes done to the library in 1.19.
                                                              • leaveyou 3 years ago
                                                                When was that ?

                                                                IIRC that was the general feeling then but the impression has changed in the mean time ?

                                                              • another_Hans_M 3 years ago
                                                                No need to disrespect Rust. I like both. And certainly they both have their proper use cases.
                                                              • olingern 3 years ago
                                                                JavaScript/TypeScript changes so much that a codebase will look very different from one year to the next. JS/TS has come a long way and needed to make substantial change, but I appreciate the slow moving, methodical nature in which the Go team moves the language and environment forward.
                                                                • shp0ngle 3 years ago
                                                                  The negative is that some issues are really hard to fix, because you don’t want to break the backwards compatibility guarantee.

                                                                  For example, there is a bug in go’s built-in HTML templating, that it misrepresent javascript backticks.

                                                                  If you do

                                                                  <script> var string = `http://google.com` </script>

                                                                  in HTML template, it will interpret // as a comment and return

                                                                  <script>var string = `http:</script>

                                                                  This is now really hard to fix; it means either rewriting the JS parser from scratch, but that is a giant change (currently the JS parser is really simple, backticks are hard to do properly without reimplementing all from scratch); the more reasonable choice would be to just ban backticks in HTML templates, but that would break backward compat.

                                                                  So there is basically an unfixable bug sitting in go html templates.

                                                                  https://github.com/golang/go/issues/9200

                                                                  • badsectoracula 3 years ago
                                                                    Can't they add an option or something that specifies how backticks are handled with the default setting to be the current (so nothing breaks) and any new code or existing code that knows about the issue can set it to a better value?
                                                                    • rytill 3 years ago
                                                                      If it’s bad enough, why not release a v2 of the library?
                                                                      • jen20 3 years ago
                                                                        The standard library seems to only be versioned with the language. An external v2 could work, but I’m not sure there’s any precedent for a v2 of a standard library package.
                                                                      • eyelidlessness 3 years ago
                                                                        > the more reasonable choice would be to just ban backticks in HTML templates, but that would break backward compat.

                                                                        Given script tags are allowed, this seems like the least reasonable choice. What other arbitrary JS features should be disallowed because the parser isn’t spec compliant?

                                                                        • diogenesjunior 3 years ago
                                                                          Why can't they just make a new version of the library for fixes?
                                                                        • Zababa 3 years ago
                                                                          > JavaScript/TypeScript changes so much that a codebase will look very different from one year to the next.

                                                                          Only if you want it to change. Our codebase is plain JS/TS, we don't use many recent features, and it's fine.

                                                                          • dreyfan 3 years ago
                                                                            Are we just ceding Javascript to Microsoft at this point due to the ubiquity of Typescript?
                                                                            • eyelidlessness 3 years ago
                                                                              If anything, TypeScript is quite deferential to TC-39. Microsoft is part of the standardization process, but certainly not the main/only driver. I don’t know where you got the impression that this is a MS issue, but TS changes because JS changes not the other way around.
                                                                              • frosted-flakes 3 years ago
                                                                                TypeScript does not output obfuscated JS. The output is completely human-readable, even if certain things don't match the source exactly. TS explicitly tries to stay in line with JS, syntax-wise.
                                                                                • threatofrain 3 years ago
                                                                                  It’s already mainstream to minify your JS anyway as part of a long build process. JS transparency is used by very few people.
                                                                                  • IshKebab 3 years ago
                                                                                    No. Typescript is really strict about being only type annotations for JavaScript (except `enum`), so I'm not sure why you'd think that makes them control JavaScript.
                                                                                    • pjmlp 3 years ago
                                                                                      It wouldn't be a loss if browsers could natively understand Typescript annotations, and even take advantage of them for the JIT.

                                                                                      Looking forward to the day, actually.

                                                                                      • IceDane 3 years ago
                                                                                        This is just plain nonsense and is bordering on being paranoid and delusional behavior similar similar to what you'd see from conspiracy theorists.

                                                                                        If you ever tried looking at the compiled code, or tried playing with the settings, you can see that typescript is able to output code which is nearly your original code copied, just without types. It all depends on which compilation target you choose. If you choose es3, it will be full of polyfills. If you choose esnext, it will be basically your code.

                                                                                    • crnkofe 3 years ago
                                                                                      I was really looking forward to getting some basic generic standard library funcs. Guess what I'm getting now is a a ton of std libraries each with a slightly different approach, slightly different bugs and update cycles which will nicely inflate the amount of tech debt in existing codebases.

                                                                                      I guess from the standpoint of a language designer it makes life a bit easier not to do anything and just cherry pick the winners of the various generic attempts that the community will create but as an app. developer I find this disturbing. Also I question the rush to a release all of a sudden. Generics took years to come to fruition. Another year for a decent stdlib won't really hurt anyone and for those that really really want it they can enable it through build constraints.

                                                                                      • nyanpasu64 3 years ago
                                                                                        C++17 introduced std::optional and std::variant, but they're not used by the standard library in 2021, as far as I've seen (unlike Rust which is better off for using them). It feels quite like a missed opportunity to produce more ergonomic APIs (though the inability to produce an optional<T&> is limiting, and std::variant is inefficient at compile and possibly runtime and apparently can't be fixed because ABI). I'm not a Go user, but I dislike multiple competing approaches to problems without clear guidance or fully embracing newer approaches.
                                                                                        • The_rationalist 3 years ago
                                                                                          How can people still use this toy language..
                                                                                          • qaq 3 years ago
                                                                                            Yes let's fracture the ecosystem with a bunch of libs doing generic map, slice etc. Cause there is no way to figure out how to do it right as this is a very novel feature that no other lang has
                                                                                            • Strom 3 years ago
                                                                                              Go is not in the business of copy-pasting other language designs. That much should be obvious by now.

                                                                                              The questions aren't around the algorithms. They're about Go specific things like how to deal with legacy std library parts that are made obsolete by generics.

                                                                                              • qaq 3 years ago
                                                                                                Yes NIH at Google is on the level of it's own. Look at any ecosystem that used this logic to push something off and you will see a badly fractured community that never fully reconsolidates. I'd rather depend on std lib with warts than have my deps depend on 3 incompatible versions of generic map from 3 dif. libs.
                                                                                                • marcus_holmes 3 years ago
                                                                                                  Simple solution: don't use a dep that uses generics until the fracturing is gone. Take the same approach as the Go team and let the use of generics mature and a consensus build on where/how they should be used.

                                                                                                  There's no need for generics in the short term. We've survived for 11 years without them, we can manage another couple while we work out how to best use them.

                                                                                                • pjmlp 3 years ago
                                                                                                  Exactly, they make users of Go copy-paste their own code instead.
                                                                                                • chrsig 3 years ago
                                                                                                  the proposal isn't to not implement them at all, it's to not immediately incorporate them in a way that they're permanently frozen.

                                                                                                  they'll implement them in some versioned package that everyone can adopt and play with, and then incorporate them.

                                                                                                  fracturing could happen. but that could happen if they immediately included it in the standard library with warts, too. I can easily imagine people creating multiple packages to overcome shortcomings of a half baked stdlib package.

                                                                                                  ..so I don't want go to follow some fearful path because of some unquantifiable risk that may or may not come to pass, and could come to pass regardless of which path they take.

                                                                                                  • jamesrr39 3 years ago
                                                                                                    To be fair, Go has quite successfully (IMO) not implemented features, waited for the community to come up with several different implementations, and then implemented that feature in a way that they like, without fracturing the ecosystem. Examples that come to mind are `//go:embed` and dependency management via `go mod`.
                                                                                                    • chrsig 3 years ago
                                                                                                      eh, go mod isn't the great example...the community was pretty fractured before that. I'd personally adopted dep right before they announced the intention to build modules...so that was kind of frustrating.

                                                                                                      in the long run i think it'll consolidate the community, but there's definitely a long tail to that timeline.

                                                                                                      • pdmccormick 3 years ago
                                                                                                        But were Go modules a better solution in that space? Should we have stuck with a less better approach (not casting a judgement on dep necessarily) just because it was an earlier attempt to deal with the same problem?