[HN Gopher] Go 1.18
       ___________________________________________________________________
        
       Go 1.18
        
       Author : mjlee
       Score  : 461 points
       Date   : 2022-03-15 17:29 UTC (5 hours ago)
        
 (HTM) web link (go.dev)
 (TXT) w3m dump (go.dev)
        
       | leetrout wrote:
       | Hooray! Couple quality of life improvements to embedded
       | filesystems... you can now use files that start with an
       | underscore :D
        
       | slicedbrandy wrote:
       | Now time to update _interface{}_ usage and shift to _any_.
       | $ gofmt -r 'interface{} -> any' -l **/*.go
       | 
       | Replace -l with -w to write.
        
         | rpk788 wrote:
         | well there goes my Hacktoberfest idea
        
         | eatonphil wrote:
         | Is there an actual difference between these or is it just
         | aesthetic? (and shorter)
        
       | crtc wrote:
       | Finally! This will be the last day I see the words "Go" "lack
       | of"/"no" and "generics" in one sentence.
        
         | uluyol wrote:
         | I'm sure you'll see plenty of comments saying "Go generics lack
         | support for X". Just ignore them -- some people seem to have
         | nothing better to do.
        
         | HideousKojima wrote:
         | I mean in Java vs. C# fights people still bring up that C#
         | generics are reified while Java generics rely on casting and
         | erase type information at runtime, so probably not.
        
       | henvic wrote:
       | Tip: If you've only heard about generics, make sure to check out
       | about fuzzing (*testing.F)!
        
         | meetups323 wrote:
         | Any idea why they have such a low byte budget? testing.Fuzz
         | would be so much more readable. I'll accept test.Fuzz if 9
         | characters is the limit for any compound identifier. Is this
         | sort of single letter class naming common in the standard
         | library?
        
           | unfunco wrote:
           | Not in the standard library in general, but in the testing
           | package it's the convention. There's _testing.B,_ testing.M,
           | _testing.T, and_ testing.F, and *testing.TB.
           | 
           | https://pkg.go.dev/testing#pkg-types
        
             | meetups323 wrote:
             | Well that's a hard pass from me. I always knew go was quick
             | to compile, I didn't know the lengths they were willing to
             | go to achieve that!
             | 
             | Case in point: it's not TB, as you stated, but rather PB.
        
           | gvil wrote:
           | it's super common everywhere, also in third party libraries
           | (`bson.M` is what exactly?). it's one of the reasons that
           | makes go a very displeasing language to work with.
        
       | mseepgood wrote:
       | Why post this useless Github link instead of the release notes or
       | the blog post?
        
         | anthropodie wrote:
         | yes @dang please re-link this post to https://go.dev/doc/go1.18
        
           | tptacek wrote:
           | He's probably not going to see this quickly; the thing to do
           | here is to mail hn@ycombinator.com.
        
           | hi41 wrote:
           | That's a cool feature you used there. I didn't know you could
           | use the at-the-rate symbol to reference a hn user and call
           | his attention! Very nice!
        
             | tptacek wrote:
             | It's not a feature, and it's not a good idea to refer to
             | people with @nicks, because Twitter's @name convention is
             | much stronger and the two don't overlap perfectly (I am
             | not, for instance, @tptacek on Twitter). I use 'nick to
             | refer to people here, in keeping with our lispy ethos, but
             | really anything other than @nick is fine.
        
               | whimsicalism wrote:
               | I would not assume any "@" is referring to a twitter
               | user, it is common across a number of apps (not to
               | mention, IRC)
        
               | opan wrote:
               | It's worth noting that on IRC it refers to someone being
               | an op, and that it's not used for pinging people. (I
               | sometimes see people who are used to other chats put the
               | @ at the start of an IRC message)
        
               | kadoban wrote:
               | On IRC, typical protocol is to just use people's
               | nickname, with a colon after it if you're replying
               | specifically to them. "@" is uncommon for tagging people.
        
         | samuell wrote:
         | Or better, the blog post, since it links to the release notes,
         | but seemingly this does not apply the other way around(?):
         | 
         | https://go.dev/blog/go1.18
        
       | candiddevmike wrote:
       | Personally, I'm waiting until 1.19 to start seriously exploring
       | generics. By then, the dust will have settled a bit, folks will
       | have some good lessons learned to share, and there may be more
       | packages in the stdlib for generics.
        
         | ainar-g wrote:
         | I feel like a lot of people will wait (although perhaps not up
         | until 1.19) for the simple reason that tooling support is still
         | not quite there yet. See [1] and the related issues. Static
         | code analysis is reasonably popular in Go projects, and just
         | disabling all failing tools until the tooling is there is not
         | something most people would agree to, I think.
         | 
         | With that said, of the tools that I use about  2/3  are already
         | reasonably compatible. Unfortunately, the other  1/3  are among
         | the most essential ones.
         | 
         | [1]: https://github.com/golang/go/issues/48525
        
       | pie_flavor wrote:
       | I wish I understood how people can say 'this will result in so
       | much more weird boilerplate garbage code' as it solves a problem
       | that has resulted in an absolutely ludicrous amount of weird
       | boilerplate garbage code. You're not trading off generic code vs
       | non-generic code. _Problems_ are generic. For solving generic
       | _problems_ , you're trading off the generic code that best
       | expresses them, for codegen, dynamic downcasting, or Ctrl-V. The
       | first two are not simpler (in the Go way) than generics, and the
       | third is an antipattern in _every_ programming environment.
        
         | dimgl wrote:
         | I'm extremely happy that generics are coming to Go, but to
         | answer your question regarding why people say this, it's pretty
         | simple: there's a lot of developers that misuse/shouldn't use
         | generics.
         | 
         | Here's an article I found just casually browsing on Google that
         | shows why this can turn out to be such a huge problem.
         | 
         | https://itnext.io/golang-1-18-generics-the-good-the-bad-the-...
        
       | voakbasda wrote:
       | I hope this gets merged into the upcoming Yocto `kirkstone` LTS
       | release branch, since that branch will use the same pinned
       | version for years to come. The previous `dunfell` LTS release
       | branch provided Go 1.14, which can no longer build the latest
       | versions of many projects.
        
       | earthboundkid wrote:
       | Now Go sucks because there are too many generics.
        
       | AaronFriel wrote:
       | My favorite feature is a tiny, couple line bug fix that I pushed
       | hard to get included during the feature freeze. Full details
       | here, but a summary is below:
       | https://github.com/golang/go/issues/51127
       | 
       | For the past ~8 years, many hundreds of people reported on GitHub
       | - and likely many multiples more have encountered and not
       | reported - a program that didn't work with the error "cannot
       | unmarshal DNS..."
       | 
       | This error seems to be caused by two things:
       | 
       | 1. DNS proxies not adhering to the DNS spec. This would be due to
       | VPNs with integrated DNS proxies such as Cisco AnyConnect,
       | internet connection sharing on Windows (which affects DNS
       | resolution in the Windows Subsystem for Linux), or even just
       | incorrectly implemented recursive resolvers. Specifically, if
       | these servers _receive_ a DNS message that utilizes RFC 1035,
       | section 4.1.4  "message compression", which is an extremely
       | simple compression scheme, then they may _transmit_ a DNS message
       | that doesn 't utilize message compression, which means the proxy
       | isn't in response size 1:1 but almost always increases the size
       | of DNS responses.
       | 
       | 2. Go's net/dns resolver enforcing a strict 512 byte limit on
       | responses. This is the same behavior as musl (and I would implore
       | a musl maintainer to increase this limit) but not in glibc or
       | most OS distributions' default DNS behavior.
       | 
       | I read every single GitHub issue related to this and found the
       | frustration of both end-users and OSS software maintainers
       | overwhelming. End users lacked the tools to diagnose why the
       | software didn't work, maintainers couldn't reproduce the issue.
       | 
       | This bug affected _major_ projects: Mesos, Docker, Consul,
       | Terraform, and more. For nearly a decade. Sometimes (as in Mesos)
       | these were projects where they controlled the DNS server and
       | client, so they could implement DNS message compression and solve
       | it. In other cases, such as with Docker or Pulumi, where software
       | runs on end-user machines, maintainers may have had to  "close,
       | can't repro" issues. The error was inscrutable and otherwise very
       | skilled maintainers wrote this off as a fluke or user error.
       | 
       | And these are just the tools that are typically used by skilled
       | technical users - usually engineers. It's hard to estimate but
       | not difficult to imagine underestimating how many bug reports and
       | issues end-users encountered where a cryptic error message, if
       | shown, never made its way to GitHub.
       | 
       | Software that works is better than software that - sometimes
       | cryptically - does not. And when things just work, well, very few
       | people using Go will realize that this fix prevented them from
       | experiencing an afternoon or a day or more of frustration; but I
       | will :) and I think that's what makes contributing to OSS
       | awesome.
        
         | ArchOversight wrote:
         | I wish I had your time and effort to be able to fix the issues
         | of split DNS in macOS being broken unless using cgo.
         | 
         | https://github.com/golang/go/issues/12524
         | 
         | This has been an open issue since 2015. It's a pain because
         | every single last tool using go cross compilation fails to use
         | the proper DNS resolver and thereby doesn't work when using
         | work VPN's.
         | 
         | This is tools like: kubectl, vault, concourse (fly), and many
         | other binaries that get built on CI, and unless the company
         | builds on macOS builders and uses CGO_ENABLED=1 DNS resolution
         | is just broken.
         | 
         | And it is increasingly frustrating.
        
           | AaronFriel wrote:
           | Very interesting and very helpful. TLD-specific resolvers on
           | Mac not working is the missing piece I needed to understand
           | why our team builds binaries on Mac and cross-compiles to the
           | other two.
        
         | mindwok wrote:
         | That was a good read. Well done pushing that forward, I believe
         | it was the right position to take.
        
         | tedunangst wrote:
         | To save a click: the fix was increasing packet size limit to
         | 1232.
        
         | sdfhbdf wrote:
         | I read through the whole issue thread. I admire your firmness
         | on pushing through while at the same time maintaining
         | professional and analytical tone in your responses. To me it is
         | a good example how I'd imagine most open-source issue
         | discussions should go. I understand both sides, and trade offs
         | taken. Nice work.
         | 
         | Although the "your best bet to get a desired change through
         | isn't via a private call with a maintainer." comment directed
         | at you made me chuckle.
        
         | tomohawk wrote:
         | Your campaign to get this fix put in should be required reading
         | for anyone involved in open source. A lot of lessons to be
         | learned there.
        
       | philosopher1234 wrote:
       | This is very exciting! Generics will be helpful for some, I'm
       | sure, but my reading of the winds is that people will find other
       | idiosyncracies of Go to latch onto and complain about. It seems
       | to me the next object of hatred is the lack of sum types.
       | 
       | I would like to understand a bit more about where a lot of the Go
       | criticism comes from. Of course some amount of it comes from
       | direct frustrations people have with the language design, but I
       | suspect that doesn't account for all of it. It seems to me that
       | the intensity with which some people fixated on the absence of
       | generics cannot be explained just by frustration with writing
       | non-generic code, which by all accounts was annoying but not
       | overwhelmingly so.
       | 
       | So, for those of you who are willing to explore the part of this
       | that goes beyond a simple rational analysis and criticism of
       | language design, whats bugging you?
       | 
       | Sometimes I think the core irritation with Go is its simplicity.
       | The suggestion that easy to learn languages can be effective too
       | is somewhat humiliating, as we get attached to the pride of
       | mastering more complex languages, and the suggestion is that some
       | of the struggling we went through was unnecessary, and that folks
       | who wont struggle as much might be able to be effective too, in
       | fact the suggestion is that maybe our pride was misplaced.
       | 
       | Theres also a suggestion, in the fact that Go has opinions, that
       | other opinions might be "wrong". I think this may bug people, who
       | would take up those other opinions or see merit in them, a lot.
       | There's also a bit of an anti-expertise "who are you, Go
       | creators, to say you know better than me how to design this
       | program/engage in software development?"
       | 
       | In any case, it's something I've been trying to figure out for a
       | while and I don't think I have a complete explanation still.
       | Curious to see what others think.
        
         | zemo wrote:
         | people hate Go because Go is unapologetically designed from the
         | framing of programmers being members of a labor class having
         | differing levels of expertise. It's not the design itself; it's
         | the design _goals_ themselves that people are opposed to.
         | 
         | This Rob Pike quote gets bandied around in these discussions:
         | 
         | > The key point here is our programmers are Googlers, they're
         | not researchers. They're typically, fairly young, fresh out of
         | school, probably learned Java, maybe learned C or C++, probably
         | learned Python. They're not capable of understanding a
         | brilliant language but we want to use them to build good
         | software. So, the language that we give them has to be easy for
         | them to understand and easy to adopt.
         | 
         | Ten years ago when I learned Go at the Recurse Center, I was
         | early in my career and I picked Go as my language of study
         | because I believed it was a good bet for my career prospects. I
         | said to myself "I bet this is the next Java, and I bet that
         | people who learned Java very early did very well for
         | themselves". This bet proved correct; Go has been enormously
         | useful to me in my career. Many people who go to RC pick
         | languages like Haskell or a Lisp instead; things that are more
         | interesting and challenging. While Haskell is well known for
         | being mentally stimulating and very enriching, it is also well
         | known for not seeing much industry adoption. You can sub a
         | handful of other languages here, but basically just think of
         | any very beautiful cutting edge experimental language that
         | doesn't have a lot of industry jobs. I'm stick to Haskell for
         | consistency in this post but you could just as easily say Lisp
         | or Scala or arguably Rust these days; it's not about a specific
         | language, it's about a specific grouping of languages that
         | prioritize the beauty of the language and the effectiveness of
         | the solo developer.
         | 
         | People get upset at Pike's framing that Go should be learnable
         | by people with less-than-expert experience. As a person sees
         | technology's ability to serve as a vehicle of class mobility, I
         | see this as a great and noble design goal, because I think
         | class mobility is fundamentally good. Ask yourself this: why do
         | people consider it _bad_ that a language acknowledge that it
         | should help not only people with lots of experience, but also
         | people with very little experience, and teams with _mixed_
         | levels of experience?
         | 
         | My experience of programming Go for ten years and for being in
         | these spaces for that time frame is that criticism of Go almost
         | uniformly comes from people who can afford to invest heavily in
         | things that have a low expected ROI; great and beautiful
         | languages that don't have a lot of job prospects. Most people
         | on Earth cannot afford the time commitment it takes to learn
         | programming at all, let alone learning aspects of programming
         | that they can't monetize.
         | 
         | I have never met a Go programmer that is bothered by the
         | existence of Haskell. I have met many, many Haskell programmers
         | that are bothered by the existence of Go. Ask yourself why that
         | is. Ask yourself why someone would be so angry about something
         | so wildly successful and useful to people. It's not even
         | remotely a two-way street; the hatred goes one way.
         | 
         | This leaves us with the final problem: why can't people
         | acknowledge that different people have different goals, and
         | that those people's goals are just as legitimate as their own?
         | Why are other people's goals threatening? It's because the
         | existence of Go and the massive success of Go causes people to
         | confront some aspect of class consciousness. It is impossible
         | to witness the enormous success of Go and not confront the idea
         | that programmers are laborers, and for some people, the idea of
         | being a member of the labor class is simply not acceptable;
         | criticizing Go thus becomes not merely an act of design
         | criticism, but also as vehicle through which the critic can
         | express something about their own socioeconomic class. There
         | are many valid criticisms of Go, but there is also a category
         | of Go criticism that exists more as a form of class signaling
         | than anything else, and in these public forums, those two forms
         | of criticism often get entangled in complex and opaque ways.
        
           | philosopher1234 wrote:
           | I love this take, its very interesting! Thanks for sharing.
        
         | stouset wrote:
         | > I'm sure, but my reading of the winds is that people will
         | find other idiosyncracies of Go to latch onto and complain
         | about. It seems to me the next object of hatred is the lack of
         | sum types.
         | 
         | This is a needlessly dismissive perspective. Put another way,
         | now that one of golang's most prominent deficiencies has been
         | addressed, people will switch their focus to other areas of
         | frustration.
         | 
         | > Sometimes I think the core irritation with Go is its
         | simplicity.
         | 
         | The core irritation (well, _my_ core irritation) around Go is
         | that this simplicity just kicks the cans of complexity and
         | verbosity downstream onto its users, and--in the worst cases--
         | hides the fact that this complexity exists, so encourages
         | writing simple, obvious, and _subtly incorrect_ solutions.
         | Subtly incorrect is by far the worst kind of incorrect, as it
         | results in code that works for all the obvious test cases but
         | breaks at 2AM in production. Go doesn 't feel simple to me. It
         | feels half-assed.
         | 
         | Let's take a recent example I had to work with: truncating a
         | string to the first 63 characters. Easy, right?
         | s = s[:63]
         | 
         | Simple, obvious, and subtly incorrect. Why? UTF-8. Strings in
         | go are just a microscopic wrapper around immutable byte arrays.
         | I could almost consider this okay if there was some type in the
         | language that wrapped a byte array and an encoding to provide a
         | real string type. But not only isn't one included, a reliable
         | one _can 't even exist_. The range keyword iterates over bytes
         | for byte arrays and over UTF-8 code points for strings and
         | there's no way to express anything different. String straddles
         | this uncomfortable middle where it's both a byte array and a
         | UTF-8 string and which one it is depends implicitly on which
         | operators you use on it. Strings are "just" a byte array,
         | except they're supposed to contain UTF-8, but not only is there
         | no way to enforce that they do, the language makes it trivial
         | to accidentally corrupt any UTF-8 string you do have (e.g.,
         | through indexing). If you're writing a function and somebody
         | passes you a string you have no way to know or enforce that
         | it's intended to bytes or ASCII or UTF-8 or any encoding
         | whatsoever without iterating through to check. There is no type
         | that actually encodes an enforced requirement of a valid UTF-8
         | string, nor can one even be written as a library.
         | 
         | So the way you're "supposed" to truncate a string is:
         | s = string([]rune(s)[:63])
         | 
         | At least I think that's the magical incantation. Do you do this
         | everywhere? Do your coworkers? Yeah, I didn't think so.
         | 
         | Compare this to Rust and Ruby, which take two diametrically
         | opposite (but both IMO reasonable) approaches. In Rust, strings
         | _are_ UTF-8. You cannot construct a String that does not
         | contain a valid UTF-8 byte sequence (at least not without
         | unsafe). You cannot perform safe operations on a string that
         | result in an invalid byte sequence. If you are handed a string,
         | you know that it contains valid UTF-8 bytes. You can iterate
         | over either the bytes or the characters, but you have to
         | explicitly decide which. In Ruby, strings are byte array  /
         | encoding pairs. It could be UTF-8, UTF-16, Shift-JIS, EBCDIC,
         | or any other encoding you want it to be. When you're handed a
         | string you can generally assume it's been parsed and validated
         | under that character set. Indexing, iteration, and other
         | operations are all encoding-aware. If you want the bytes, you
         | can choose to access them.
         | 
         | The string equivalent in golang is, to put it bluntly, half-
         | assed. It's mostly just a byte array but some keywords assume
         | it's UTF-8. If you're given a string you generally assume it's
         | UTF-8 but there's no reasonable expectation that it's valid
         | since the language makes it ridiculously easy to violate the
         | encoding rules. Go strings aren't even a decent building block
         | for an encoding-aware type since range can't be made to work on
         | other encodings. For a language written by none other than Rob
         | Pike himself, I simply cannot fathom how golang arrived at this
         | design.
         | 
         | Keep in mind this is just one of a myriad places where the
         | language punts complexity to the user but, at best, doesn't
         | give them the tools to actually reliably handle it and, at
         | worst, pretends like the complexity doesn't even exist so it's
         | not even obvious something needed special care in the first
         | place. Simple, obvious, and subtly incorrect.
        
         | ainar-g wrote:
         | > It seems to me the next object of hatred is the lack of sum
         | types.
         | 
         | Sum types may be coming in a close future release, since the
         | notation                 type T interface {               int |
         | string       }
         | 
         | that can currently only be used for constraints on type
         | parameters can be "easily" made to be a runtime thing as well.
         | I cannot find the GitHub issue right now (perhaps, it wasn't an
         | issue, but a comment in a very long thread, and GitHub is being
         | annoying with those), but it seems like nobody is currently
         | opposed to that, and the only reason it didn't make it into
         | 1.18 is that it's already a pretty big language change.
        
           | earthboundkid wrote:
           | Yes, the only downside I see is that if you do:
           | type Number interface { int | int64 | int32 }         var n
           | Number
           | 
           | The default value for n has to be nil, rather than 0, because
           | Go can't choose between the types (int 0, int64 0, etc.). And
           | of course, you can't do n + x (assuming x is also a Number)
           | because x might be a different kind of number. Still, it's a
           | pretty good simplification from the current restrictions, and
           | it builds well on existing concepts.
        
         | mcronce wrote:
         | > So, for those of you who are willing to explore the part of
         | this that goes beyond a simple rational analysis and criticism
         | of language design, whats bugging you?
         | 
         | Error handling is a big one for me. This could be generalized
         | to lack of expressivity; it takes an unreasonably large amount
         | of code to accomplish anything. Generics will help with the
         | general case, but they don't do anything for error handling.
         | 
         | Lack of sum types, as you already mention, are another.
         | 
         | Go really likes forcing you to either write a ton of tests or
         | discover your errors in production. More expressive features
         | (sum types, etc) effectively mean that compiler provides those
         | tests to me for free. _Can_ I write them myself? Yes,
         | obviously, but that brings us right back to having to write way
         | too much code to accomplish anything.
         | 
         | Farther down the list is escape analysis. Rather than just
         | giving me control over whether allocation happens inline or
         | indirect, if I have some performance critical submodule, I have
         | to sit there and box with escape analysis; this is not only
         | time consuming, but extremely brittle.
         | 
         | https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-...
         | is a good read for fairly specific issues that _mostly_ haven't
         | directly impacted me, but on the rare occasion they have,
         | they've been infuriating.
        
         | nicoburns wrote:
         | I would suggest that the core complaint is with the lack of
         | ability to create abstractions, which leads to writing a lot of
         | boilerplate. Which in turn makes Go code quite hard to read for
         | anyone who thinks about programming from a top-down perspective
         | doesn't for example want to have to decipher loop indexes to
         | determine that the code is doing a .filter().map() operation.
        
           | Thaxll wrote:
           | I disagree, Go is easier to read than most modern languages,
           | it's easier because it has a few keyword and did not add
           | major features in the last 15 years.
           | 
           | I can't say the same for Java / C#, Rust / C++ etc ...
        
             | nicoburns wrote:
             | I think that's a valid perspective. But there are many of
             | us who don't find Go harder to read than those languages
             | (well, maybe not C++). I think we must recognise that to
             | some extent simplicity is subjective. What is easy to one
             | person isn't necessarily easy to another and vice-versa.
             | 
             | Personally, I _think_ in abstractions. So a language that
             | represents those directly is much easier for me to reason
             | about than one that makes me constantly translate those
             | low-level procedural code and back again.
        
               | philosopher1234 wrote:
               | Perhaps the trouble is when you encounter other peoples
               | abstractions, or when you return to abstractions you've
               | long since discarded :)
        
               | nicoburns wrote:
               | The key abstractions that I want access to are standard
               | ones like "map", "filter", "reduce", and data structures
               | like "Option", "Result", "Future, "ConcurrentHashMap".
        
             | kaba0 wrote:
             | Then logically brainfuck should be much easier to read with
             | only the 8 or so "keywords" it has.
             | 
             | Complexity can not generally be decomposed into smaller
             | parts.
        
         | matthewmacleod wrote:
         | I think my biggest non-specific, slightly silly irritation when
         | using Go is just how _annoying_ I find it to write clear code
         | in it, because the focus on simplicity feels like it too often
         | comes at the expense of clarity, correctness, and
         | expressiveness.
         | 
         | I don't like that I'm not able to express simple constraints
         | that I find a really important for improving code quality in
         | other environments - things like "this field cannot be nil and
         | it's a programming error if it is", or "all possible values of
         | this field must be handled". There are lots of other bits, but
         | I'd say the general pattern is being quite frustrated about
         | _having to do and remember things that the computer should be
         | handling for me_ - such that working in Go always feels like
         | having a small rock in my shoe.
         | 
         | It's a shame, because as a language--and wider ecosystem--it
         | gets so much stuff really right.
        
         | rat9988 wrote:
         | > I would like to understand a bit more about where a lot of
         | the Go criticism comes from
         | 
         | Because I loved the language so much but I feel like it decided
         | to be on the wrong level of abstraction, making many things,
         | uselessly frustrating and verbose. What can be a very readable
         | code in other languages can be hard to read in go because of
         | its verbosity. And the lack of generic has been very limiting
         | of a while, and many discussions with the main team turned to
         | "what are your usecases that really need generic". So I felt
         | like the language won't evolve the way _I_ wanted it, the
         | despite its redeeming qualities.
        
           | throwaway894345 wrote:
           | > What can be a very readable code in other languages can be
           | hard to read in go because of its verbosity
           | 
           | I suspect that a lot of people conflate "readable" and
           | "terse" or "abstract". For example, beyond one or two chained
           | methods, a foos.map(...).reduce(...) style quickly becomes
           | unreadable while the equivalent for loop is still easily
           | understood (this is a large part of the reason why
           | complicated list comprehensions are discouraged in many parts
           | of the Python world). It's also why it's often easier to
           | understand error paths in Go than in a language which makes
           | heavy use of exceptions despite differences in boilerplate.
        
             | rat9988 wrote:
             | I see where you come from with those super smart one liners
             | (guilty of it when I started programming). But sometimes,
             | you can do something nicely in one line instead of three or
             | four, and it makes it easier to parse.
        
               | throwaway894345 wrote:
               | I agree, but those one-liners win by only a little bit
               | when they do win (e.g., it's only a little easier to read
               | foos.map(...) than it is to read the equivalent for loop)
               | but they lose by a lot when they lose (it's a _lot_
               | harder to read
               | .map(...).filter(...).flat_map(...).reduce(...) than the
               | equivalent for loop). Generics tend to win by a lot in
               | very specific, rare cases--so I appreciate that Go will
               | have better support for those cases, but there 's no way
               | the community will restrain themselves outside of those
               | cases (no language community has succeeded in this
               | capacity to date).
        
               | kaba0 wrote:
               | I don't know, I have seen my fair share of indecipherable
               | for loops depending on some side effect shared by two-
               | three loops, where you don't even stand a chance to
               | understand it.
        
         | [deleted]
        
         | kansface wrote:
         | > It seems to me that the intensity with which some people
         | fixated on the absence of generics cannot be explained just by
         | frustration with writing non-generic code, which by all
         | accounts was annoying but not overwhelmingly so.
         | 
         | You speak for yourself here! Miles of copy pasted code,
         | slightly altered who knows how, impossible to refactor without
         | either using code generation or eschewing type safety
         | altogether was my experience. Its impossible to write entire
         | classes of general purpose libraries with type safety! Its just
         | beyond belief to me that "copy paste" is an actual, bona fide
         | best practice in the community, or that a 'map' function is
         | unexpressible!
         | 
         | > There's also a bit of an anti-expertise "who are you, Go
         | creators, to say you know better than me how to design this
         | program/engage in software development?"
         | 
         | Go the compiler/runtime is super impressive! Cross compiling
         | small, binaries with a switch is awesome, so kudos! Go, the
         | language, on the other hand, sucks; it actually sucks so much,
         | that historically, we couldn't even write libraries to work
         | around the things that suck. That is frustrating!
        
         | throwaway894345 wrote:
         | > Generics will be helpful for some, I'm sure, but my reading
         | of the winds is that people will find other idiosyncracies of
         | Go to latch onto and complain about. It seems to me the next
         | object of hatred is the lack of sum types.
         | 
         | I'm a big Go proponent, and I'm pretty "meh" on generics.
         | They'll make some code easier to read and write, but they'll
         | make a lot of code a lot harder to read (because contrary to
         | popular belief, "readability" doesn't always increase with
         | abstraction or terseness).
         | 
         | That said, sum types would genuinely be helpful--the
         | workarounds are error prone (making sure all cases are handled
         | by code) and inefficient (unnecessary allocations if the
         | implementation is backed by interfaces or wasted memory if it's
         | struct with a field per variant). Note that simply supporting
         | sum types doesn't guarantee that they'll be implemented
         | _efficiently_ --I'm afraid of the possibility that the Go
         | community might settle for an interface-based implementation
         | rather than a union-based implementation.
         | 
         | On balance, however, Go is still the most productive language
         | I've ever used (and by a healthy margin). People make way too
         | big a deal about type system minutia (having a basic type
         | system is important, but going too far beyond that can be
         | counterproductive) and they are far too forgiving for things
         | like bad tooling, poor performance, or impoverished standard
         | libaries.
        
           | djbusby wrote:
           | What do you build where you see that "healthy margin"? I
           | build mostly webApp, and API services (boring business
           | stuff). Reaching for Go or PHP is about the same (read JSON,
           | business rules, database). For this stuff PHP was hardly
           | better than CGI-Perl - except for application performance -
           | where PHP was better than CGI and Go is better than both.
           | What am I missing in using the tools that I don't see that
           | margin? Maybe I'm measuring the wrong thing?
        
             | eacafdcbac wrote:
             | I've only worked in PHP once, in college, so take the
             | following with whatever level of credibility you wish. I
             | generally work in infosec related projects that often come
             | at strange intersections, such as embedded systems and web
             | applications or real time operating systems in safety
             | critical situations which must deal with data from
             | unreliable or weakly secured sources (802.11, LoRa etc.)
             | So, mostly my experience with Go is the need to write one-
             | off tools, which usually provide either a CLI or web-ui, to
             | inspect things embedded devices are doing as a sort of
             | "black box."
             | 
             | I'm sure generics are going to be useful in some instances.
             | Also of note 1.18 is bringing built in fuzzing, which is
             | nice.
             | 
             | Where I'm getting my margin of benefit over writing tooling
             | in say Python or Ruby, or other languages that fit this
             | domain:
             | 
             | 1. Fewer choices: The build system, module layout, and
             | networking APIs don't lead me down the road of trying to
             | figure out which library is best, thereby wasting time
             | learning different libraries. I have never had any desire
             | to google around for external libraries etc. Everything
             | seems to just work fine.
             | 
             | 2. Clear design intent: Once you've figured out what you're
             | supposed to do with language idioms, like passing around
             | ReadClosers or whatever it becomes super easy to read code
             | written by other people who've also come to understand the
             | intent. I don't notice this until I try to go back to doing
             | something in Python and remember how vastly many approaches
             | folks take to the same problem (like how should a database
             | object be passed around.)
             | 
             | 3. Works for my workflow: I spend most of my life in
             | terminals fussing with serial communication, or fighting
             | with mqtt or an APK that won't load like I expect, etc. The
             | tooling with Go for nvim is incredible. I've found that now
             | that I've gotten fairly fluent in the language I will often
             | crack off small scripts in Go to automate dumb things I
             | don't want to do in Bash or whatever, this is maybe an
             | anti-pattern, depending on who you talk to.
             | 
             | Summary: _My_ big margin over other languages just comes
             | from consistency of design and interfaces and the fact that
             | Go integrates with my workflow. It 's very easy to figure
             | out how to do a thing the first time I'm working on it.
             | It's also easy to throw together a one off tool in an
             | afternoon, use it for two weeks, push it up to my github
             | and forget I did it until the next time I need it.
             | 
             | YMMV
        
               | matwood wrote:
               | > I've found that now that I've gotten fairly fluent in
               | the language I will often crack off small scripts in Go
               | to automate dumb things I don't want to do in Bash or
               | whatever, this is maybe an anti-pattern, depending on who
               | you talk to.
               | 
               | I do the same. Most everything you need for quick
               | scripting against services and the like is built in. No
               | hunting down libraries. Then the build output is a fully
               | contained binary that can run on my m1 mac, x86 server,
               | whatever.
               | 
               | > It's also easy to throw together a one off tool in an
               | afternoon, use it for two weeks, push it up to my github
               | and forget I did it until the next time I need it.
               | 
               | And when you do go back to it, the code is easy to read
               | and understand.
        
             | rob74 wrote:
             | Comparing Go and PHP, as a compiled language Go's
             | performance is undeniably better. Plus it has a cleaner
             | design without all the cruft that accumulated in PHP over
             | the decades (in PHP's favor however, you have utility
             | functions that make it really easy to accomplish basic
             | tasks, such as `json_decode` and `file_get_contents`, which
             | are not so straightforward in Go).
             | 
             | One example I'm currently confronted with: I'm writing a
             | long-running backend task in PHP, and since the rest of the
             | backend is based on Laravel, it's using Laravel too. The
             | script doesn't really do much, and as far as I can see
             | there should be no memory leaks, but unfortunately it can
             | still only run for ~ 3 hours before it quits because of
             | running out of memory. I'm sure it will be real fun
             | debugging that. Makes me want to switch to Go...
        
               | djbusby wrote:
               | Used xdebug profiler, right?
        
             | throwaway894345 wrote:
             | It's entirely possible that for your purposes, Go doesn't
             | yield much of a benefit. I see that "healthy margin" fall
             | out of a bunch of different aspects rather than one big
             | aspect:
             | 
             | 1. Working with basic static type support helps me to not
             | worry about silly errors which helps me move faster. Beyond
             | that, it helps team members understand each other's code
             | correctly--when working with dynamically typed languages,
             | type documentation would often be incomplete or become
             | outdated/incorrect and I would spend a lot of time trying
             | to understand the correct type. Moreover, static typing
             | enables a lot of IDE tools that save a ton of time (e.g.,
             | goto definition). This is probably more of an advantage for
             | more complex applications rather than simpler CRUD apps.
             | 
             | 2. Performance. I've worked on a lot of Python projects
             | where we've spent a _lot_ of time optimizing, and all of
             | the options for optimizing Python have hidden pitfalls
             | (e.g., typically  "just rewrite the slow parts to use
             | multiprocessing/C/etc" end up slowing your program down
             | because the costs of marshaling data exceed the gains never
             | mind the costs of maintaining that code). Idiomatic,
             | unoptimized Go is already 10-100X faster than Python and
             | you can pretty easily squeeze more performance out of it
             | via parallelism or moving allocations out of tight loops).
             | If application performance isn't important to you, then
             | this probably won't be particularly compelling.
             | 
             | 3. Deployment artifacts. By default, Go compiles to single,
             | reasonably small, static binaries so you can pretty easily
             | build and distribute command line tools to your entire
             | team, you can build tiny Docker images (tiny images mean
             | shorter iteration loop in a cloud environment), etc.
             | 
             | 4. Simpler Docker development workflow. With dynamic
             | languages, there's not a great way to iterate. Normally,
             | you'd want to mount your development directory in a volume,
             | but Docker Desktop (or whatever it's called these days)
             | will eat all available CPU marshaling file system events
             | across the VM guest/host boundary, so you end up having to
             | do increasingly convoluted things.
             | 
             | 5. Employing and onboarding. Anyone from any language can
             | be productive in Go in a few hours. No need to restrict
             | your hiring pool to "Go developers". Moreover, for other
             | languages, it's not sufficient to merely know the language,
             | you may also have to know the framework, IDE, build
             | tooling, etc that the team uses. The ramp up time can be
             | significant, and this can be a meaningful problem in an
             | industry where people change teams or even companies after
             | a few months or years.
             | 
             | This list is pretty narrowly fixated around dynamic
             | languages because I've done more Python development than I
             | have Java/etc and also because your point of reference is
             | PHP. It's hard to compare Go generally to all other
             | languages.
        
               | eacafdcbac wrote:
               | It was fun to read your response compared to mine :) You
               | mentioned some things I missed, and we had pretty
               | different reasons. Just shows a well made tool carries a
               | variety of values for a variety of users.
        
           | jchw wrote:
           | Sum types and pattern matching would be great, and I think
           | they would be much more useful than generics. Unfortunately,
           | Go lacking generics has become a legitimate meme. An article
           | evangelizing .NET recently popped up here and annoyingly used
           | Go's slowness to get generics as a legitimate point.
           | 
           | I don't think generics will greatly damage what Go has going
           | for it, but I hope it also doesn't block the way for better
           | error handling, sum types, and other things that could
           | potentially improve code robustness.
        
             | throwaway894345 wrote:
             | I guess I disagree about the legitimacy of the meme or any
             | point that could be made from Go's "slowness to get
             | generics". The only people who think that generics will be
             | a slam-dunk net benefit for Go are the folks who can't
             | articulate the costs associated with generics. The actual
             | net benefit is so small and the error margins are so wide
             | that it is entirely reasonable that Go didn't rush
             | generics, instead prioritizing larger and more certain
             | gains.
        
               | jchw wrote:
               | I mean legitimate meme as in, it is a point that is
               | widely assumed true at this point, not as in it is
               | actually accurate in its assessment. I never really
               | thought Go needed generics.
        
           | jrockway wrote:
           | I think people are going to go off the rails with functions
           | that abstract over for loops. I see it all the time in
           | Javascript code, where people iterate over an Array multiple
           | times because that's what the API makes easy.
           | 
           | For example, say you want to separate a slice into two
           | slices, one that contains matches and one that contains
           | everything else. Right now, you'd just write:
           | var matches, mismatches []whatever        for _, x := range
           | xs {            if x == condition {                matches =
           | append(matches, x)            } else {
           | mismatches = append(mismatches, x)            }        }
           | 
           | But soon, people will be golfing that down to:
           | matches    := slices.Search(xs, func(x whatever) bool {
           | return x == condition })        mismatches :=
           | slices.Search(xs, func(x whatever) bool { return x !=
           | condition })
           | 
           | This is twice as slow, but it's less lines so I have a
           | feeling that people will have an uncontrollable desire to use
           | it as often as possible. I hope that my feeling is wrong.
           | 
           | (Do note that slices.Search is not a real function yet.)
        
             | cheriot wrote:
             | My experience writing Scala was that there's a modest list
             | of ways people iterate over collections that covers 99.9%
             | of cases. For this example, many languages have a Partition
             | function.                  matches, mismatches    :=
             | slices.Partition(xs, func(x whatever) bool { return x ==
             | condition })
        
             | TimothyBJacobs wrote:
             | A common API is something like lodash's `partition` so you
             | don't have to loop over the same Array multiple times:
             | https://lodash.com/docs/#partition
        
             | Groxx wrote:
             | While I agree that it'll probably increase, for non-
             | performance-sensitive stuff (or small lists) that doesn't
             | really seem like a problem. And for cases where it is, the
             | answer is the same as it has always been: profile and
             | optimize.
             | 
             | Though now it's much easier to make a "matches, mismatches
             | := slices.Split(xs, func(x whatever) bool { return x ==
             | condition })" helper, so that improvement even reduces the
             | number of lines further.
        
             | akavi wrote:
             | Go has multiple return values, so you could instead do:
             | matches, mismatches := slices.Partition(xs, func(x) bool {
             | return x == condition });
        
             | Zababa wrote:
             | This is a wild guess, but maybe the Search function could
             | be a bit better than expected if it was a bit smarter about
             | allocation size than the regular version you posted. From
             | what I understand, the initial capacity of slices is 0,
             | which would mean that you get a few reallocations with the
             | "naive" version. Search, on the other hand, could allocate
             | a slice with a capacity that's a half of xs, so you only
             | need one reallocation at worst.
             | 
             | This, mixed with the "Partition" function proposed by
             | sibling comments (which would only iterate once) could lead
             | to code that's faster than the regular approach, while also
             | being shorter to write.
             | 
             | On the other hand, it's not as free as it seems, as now
             | developers have to know the Partition function, and how it
             | works. It may also have pitfalls that I haven't considered.
             | As always, it's hard to find the perfect sweet spot between
             | how much stuff developers should know and how much stuff
             | should be explicit in the code all the time.
        
           | [deleted]
        
         | didibus wrote:
         | > So, for those of you who are willing to explore the part of
         | this that goes beyond a simple rational analysis and criticism
         | of language design, whats bugging you?
         | 
         | I think the reason Go gets a lot of criticism is that at a
         | language level it misses a lot of constructs and features. So
         | for everything it doesn't have, you'll find someone who is
         | really used to leverage those constructs or features when they
         | program and who favor that style, thus they will be bothered
         | that Go doesn't have them, as it makes it less enjoyable for
         | them to use Go.
         | 
         | Now normally this wouldn't be an issue, you'd say, just don't
         | use Go. But here's the thing, the best part about Go isn't the
         | language, but the compiler and runtime. That's the combination
         | which attracts a lot of criticism, because everyone would like
         | to be able to use the Go compiler and runtime since it creates
         | beautifully efficient, small and low memory binaries with
         | cross-compilation, and it has a good set of libraries.
         | 
         | I'd say on that front Go is unparalleled honestly, I can't
         | think of any other compiler that can produce binaries for
         | various targets that easily. Its cross-compilation is simply
         | excellent.
         | 
         | That means everyone would want to use Go, but not because of
         | the language, but because of the compiler and runtime. As all
         | these people come to Go, they're forced to use the language,
         | and very quickly realize this doesn't have the features or
         | constructs that they'd want to program with, and there goes the
         | criticism.
         | 
         | The trade-off is just hard to swallow, if you come from a more
         | expressive and powerful language, with more features or styles,
         | the Go language will be a harsh reality of how minimal it all
         | is, so much so that they decide not to use Go.
         | 
         | So what's happening is a bunch of people are waiting for Go to
         | have feature X,Y,Z before they jump back to Go, and that
         | creates loud voices, and the reason is that they want to use Go
         | the same way they currently program, but have access to its
         | awesome compiler and runtime.
        
           | rob74 wrote:
           | What people don't realize is that the simplicity of the
           | language also contributes to the compilation speed, so adding
           | features to the language at the same rate as other projects
           | (that I don't want to mention here) would jeopardize one of
           | Go's major advantages.
        
             | erik_seaberg wrote:
             | Our dev team is made of meat. Forcing us to read and write
             | boilerplate is not only demoralizing and error-prone but
             | also millions of times slower than having the compiler
             | generate that code.
             | 
             | This might have been a good tradeoff when they could barely
             | fit a C compiler in a PDP-7, but that was half a century
             | ago.
        
           | jhgb wrote:
           | > I'd say on that front Go is unparalleled honestly, I can't
           | think of any other compiler that can produce binaries for
           | various targets that easily. Its cross-compilation is simply
           | excellent.
           | 
           | Zig, perhaps? My impression is that it's similarly capable.
        
           | andyfleming wrote:
           | This is spot on, for me. The compiler and runtime are
           | attractive, but the missing language niceties are an
           | annoyance.
        
           | kaba0 wrote:
           | > since it creates beautifully efficient, small and low
           | memory binaries with cross-compilation, and it has a good set
           | of libraries.
           | 
           | Other than good cross-compilation, I really don't see any of
           | that. Even niche languages that have been around forever hit
           | this exact trio like D. Also, the performance is ain't that
           | good to begin with, for more complex scenarios the
           | comparatively dumb GC of Go will be a bottleneck, compared to
           | something like Java.
        
         | bcrosby95 wrote:
         | For some, generics will be enough. For others, it won't. It's
         | the nature of people rather than a person - there's lots of us
         | and we all have our own preferences.
         | 
         | Personally, lack of generics never kept me out of Go. I did a
         | lot of programming in it for about a year when 1.0 first
         | dropped. I think it is a fine language, both with and without
         | generics.
         | 
         | I do prefer simpler languages though - those that give me broad
         | tools to accomplish many tasks rather than many tools to
         | accomplish specific tasks.
        
         | goodoldneon wrote:
         | A more robust type system can help you deal with coordination
         | between various nooks of a codebase.
         | 
         | For example, let's say our platform supports multiple
         | authentication methods. If we need to add a new auth method,
         | how do we know all the spots we need to update? TypeScript can
         | handle this using a sum type:                 type AuthMethods
         | = "push" | "sms" | "fancy_new_thing"            // No errors
         | const authMethodHandlers: {[key in AuthMethods]:
         | CallableFunction} = {           push: () => {},           sms:
         | () => {},           fancy_new_thing: () => {},       }
         | // Error: Property 'fancy_new_thing' is missing       const
         | authMethodTitles: {[key in AuthMethods]: string} = {
         | push: "Push",           sms: "SMS",       }
         | 
         | With the above approach, static analysis tells us when we
         | missed a spot. That adds a ton of safety and expedites feature
         | work (since engineers don't need to manually find all the spots
         | that need updating).
        
         | keybored wrote:
         | This comment has the tone of being genuinely inquisitive, yet
         | it mostly comes up with negative and depraved reasons for as to
         | why someone one might dislike $lang.
         | 
         | - Rational reasons (frustrations with the language design) are
         | briefly acknowledged but then some reason left by the wayside
         | 
         | - It is suggested that people don't have principled objections
         | to $lang; they will "latch onto" something else if $misfeature
         | is fixed
         | 
         | - Simplicity, a universally praised quality, might be the
         | problem
         | 
         | - ... Because it can "humiliate" someone who has wasted time on
         | needless complexity
         | 
         | - "$lang has opinions", which all languages have whether they
         | acknowledge them or not. Why should this bug people especially
         | when it comes to $lang?
         | 
         | - "Anti-expertise" for some reason, even though creating any
         | "enterprise-ready" language takes expertise and many years of
         | effort. (This also seems to be at odds with the "anti-
         | simplicity" point?)
         | 
         | - ... But aren't then people who argue _for_ $lang also anti-
         | expertise? They are after all taking a stance on something that
         | they are not experts at; they should take a neutral stance and
         | defer to the experts
         | 
         | I would say that it is rude to suggest that someone might not
         | _really_ be arguing against X and instead ask what they are
         | _really_ upset about, since the follow-up questions and
         | implications are absolutely _never_ flattering. They inevitably
         | just dive into the gutter with suggestions like  "maybe
         | simplicity humiliates you".
        
           | stouset wrote:
           | This needs to be higher up, and summarizes my main _cultural_
           | oppositions to golang. I 'll also add:
           | 
           | - Extensive laundry lists of frustrations, sharp edges,
           | antipatterns, and ways the language makes it trivial to write
           | incorrect code are dismissed as nits or minor annoyances.
           | 
           | - Missing features that have no way of being worked around
           | are dismissed off-hand as unnecessary complexity.
           | 
           | - The language authors repeatedly ignore mistakes learned
           | from other language projects and rush headlong right back
           | into them, with predictable consequences.
           | 
           | - Verbosity is mistaken for "simplicity" while bugs scaling
           | roughly linearly with lines of code is quite literally one of
           | the few reliable bits of data we actually have in this
           | industry.
        
           | philosopher1234 wrote:
           | You may think these reasons are negative or depraved, but
           | they are none the less legitimate reasons that motivate real
           | people. Why should we pretend they can't possibly be a
           | factor?
        
         | candiddevmike wrote:
         | I think Go's criticisms come from elitism more than anything--
         | folks can't flex their algebraic programming muscles and
         | instead have to do error checking inline or do some WET things
         | due to lack of generics like some amateur.
         | 
         | To me, Go is never the wrong choice, but it may not be the best
         | choice for some projects.
        
           | quaunaut wrote:
           | I'm not sure it's elitism to be looking for type-system
           | features that are well-over a decade old and generally non-
           | controversial and considered vast positives.
           | 
           | I don't think they necessarily need to go crazy in this
           | regard(as simplicity is one of Go's best strengths), but I
           | don't think it's elitism.
        
           | throwaway894345 wrote:
           | I'm a Go proponent, but I also feel this. Sometimes I want to
           | be very abstract and clever. I've written a static site
           | generator in Rust, not because a Go version would be too slow
           | or error prone, but because I liked the idea of being
           | gratuitously abstract and efficient. I feel clever and I like
           | the aesthetic of very abstract programs. But this is almost
           | always at-odds with the objectives of software development--
           | very abstract/terse code is often much harder to understand
           | than concrete/verbose code. There are significant material
           | advantages to being able to onboard a developer with zero
           | language experience to a project in a matter of hours rather
           | than weeks or months.
        
             | vlunkr wrote:
             | Agreed. I don't think the hate is that hard to understand.
             | If you're coming from a more expressive language (which is
             | most of them), it's a bit of a shock. I got over it and
             | learned to love it, but I've seen others that don't, and I
             | understand.
        
           | didibus wrote:
           | I don't think Go's criticism only comes from advanced type
           | folks.
           | 
           | People criticize that handling errors is manual, annoying and
           | error prone.
           | 
           | People criticize that you can't implement your own or new
           | data-structures generically, nobody wants to use a non-
           | generic data-structure, and Go's own data-structures are
           | generic, so people complained that users couldn't do the
           | same.
           | 
           | People criticize that the lack of higher level list
           | comprehension or stream-like API for data manipulation is
           | tedious. Implementing a filter as a for loop every time gets
           | repetitive.
           | 
           | People criticize that duck typed interfaces can make it hard
           | to track what implements what, and if it makes logical sense
           | or not.
           | 
           | Etc.
           | 
           | Those are things Java and Python programmers are used too for
           | example, so it's not like the criticism is just from Haskell
           | folks.
        
         | kevinmgranger wrote:
         | I like parts of Go. It's refreshing. I'm excited for this
         | release. What I don't like is how its weak parts are
         | consistently defended instead of having its shortcomings be
         | acknowledged.
         | 
         | Before any rational analysis and criticism can begin, we need
         | to look at the context of these arguments. I'll do that through
         | some of the comments on this post.
         | 
         | - Issues people bring up are dismissed as non-issues or as
         | personal preference / opinionated, regardless of their impact.
         | 
         | - Critics are asked for rational analysis, but proponents are
         | allowed to use something as airy as "simplicity", a word that
         | has essentially lost all meaning in programming.
         | 
         | - Missteps by representatives / stewards of Go are given the
         | most charitable interpretation, critics less so.
         | 
         | - Finally, in so many cases, counterarguments to critics are
         | dripping in condescension.
         | 
         | I don't think folks are going to get rational analysis. I also
         | don't think they actually want it, whether they realize it or
         | not.
        
           | kevinmgranger wrote:
           | In case anyone is interested, here are my technical critiques
           | of Go:
           | 
           | - Boilerplate increases the surface area that a bug can hide
           | in. The fact that most of the boilerplate is around error
           | handling is especially worrying. Yes, the flexibility of
           | "Errors are values"[1] is nice. But I also don't know any
           | languages where errors _aren't_ values, so the main value add
           | seems to be reduced boilerplate compared to individual
           | try/catches around each function call.
           | 
           | - Go manages to repeat the Billion Dollar Mistake[2]. Things
           | like methods working on nil receivers is cool, but not worth
           | the danger or messiness.
           | 
           | - Even worse, for a language that claims to value simplicity,
           | the fact that nil sometimes doesn't equal nil[3] is...
           | honestly, I can only consider that a bug.
           | 
           | [1]: https://go.dev/blog/errors-are-values
           | 
           | [2]: https://www.infoq.com/presentations/Null-References-The-
           | Bill...
           | 
           | [3]: https://go.dev/doc/faq#nil_error
        
         | andrewf wrote:
         | I work at a Go shop that was a Python + RoR shop when I joined.
         | I don't dispute Go's benefits at our scale. As a matter of
         | personal preference, I don't enjoy Go.
         | 
         | Go is Blub (http://www.paulgraham.com/avg.html). I think the
         | industry is in a place where Blub makes sense! Lots of VC money
         | is floating around, and schools are training a lot of people to
         | hire with that money. Commercially relevant ideas most often
         | succeed by raising a ton of money, then hiring a ton of people
         | to realize the vision. In the Blub essay's terms, a modern
         | company doesn't _want_ to beat the average, they want to
         | reliably hit the average with the 10s or 100s of people they
         | 're hiring.
         | 
         | This resembles the conditions at Google when Golang was
         | conceived, a lot more than the "4 people want to max their
         | individual leverages, whilst eating rice and beans to extend
         | their runway" world the Blub essay was inspired by.
        
           | throwaway894345 wrote:
           | Go wins because it's _generally_ simple and consistent.
           | People like simplicity rather than kitchen-sink languages.
           | And this doesn 't only apply to the grammar and type system,
           | but also to the tooling--Go doesn't require you to:
           | 
           | * Pick a testing framework / runner
           | 
           | * Learn a DSL to manage dependencies
           | 
           | * Learn how to configure the build system to ship static
           | binaries
           | 
           | * Debate code formatting rules
           | 
           | * Build a CI pipeline to build and publish source code
           | packages
           | 
           | * Build a CI pipeline to build and publish documentation
           | packages
           | 
           | * Tune a GC for low-latency + low-memory
        
             | jimbob45 wrote:
             | I don't know if it's that people like simplicity as much as
             | simple things should be done simply. If I'm in C and I want
             | some user input and I want to concatenate that input to
             | another string, I have four hours minimum research ahead of
             | me to not add a terrible vulnerability to my application
             | right off the bat. User input should be simple in the
             | simple case with complexity hidden behind weird toggles.
             | 
             | Git is great with this. You can get by just fine in 99% of
             | cases with git add, commit, and push and those three could
             | be explained even to a child. However, you can also fine-
             | tune your pipeline just the way you like with Git's endless
             | tweaks.
        
             | zozbot234 wrote:
             | > Go wins because it's generally simple and consistent.
             | People like simplicity rather than kitchen-sink languages.
             | 
             | Rust often gets accused of being a "kitchen sink" language,
             | but the Rust folks have _tried_ doing the simple thing and
             | it came with severe limitations - Rust 0.x was pretty much
             | indistinguishable from a glorified Go. It even had green
             | threads and GC!
             | 
             | It's no coincidence that they, much like Go, provide a test
             | framework, build system, dependency management, CI, code
             | formatting etc. out of the box. Because these things
             | meaningfully improve productivity.
        
               | throwaway894345 wrote:
               | > Rust often gets accused of being a "kitchen sink"
               | language, but the Rust folks have tried doing the simple
               | thing and it came with severe limitations - Rust 0.x was
               | pretty much indistinguishable from a glorified Go. It
               | even had green threads and GC!
               | 
               | Rust is certainly a big language, but its features work
               | together toward a coherent philosophy/paradigm, so it
               | isn't really what I think of as a "kitchen-sink
               | language". C++, Java, C#, etc have accumulated features
               | from different languages and paradigms based on what was
               | fashionable at the time rather than based on an
               | overarching philosophy or paradigm.
               | 
               | That said, it isn't that Rust's "bigness" absolved it
               | from limitations--it just opted for _different
               | limitations_ : notably a less productive programming
               | model. That tradeoff makes sense in the context of Rust's
               | charter--to be a maximize for safety and performance--but
               | it's not an optimal tradeoff for general purpose software
               | development (at least not as it exists today where
               | productivity is king).
               | 
               | > It's no coincidence that they, much like Go, provide a
               | test framework, build system, dependency management, CI,
               | code formatting etc. out of the box. Because these things
               | meaningfully improve productivity.
               | 
               | Agreed. I think Rust gets a lot of tooling and ecosystem
               | stuff right (because these don't require it to compromise
               | on its charter).
        
           | FpUser wrote:
           | Quite frankly Paul's article makes little sense to me. Unless
           | you trying to code in some brainfuck using language A vs
           | language B is of little concern from my experience. I will of
           | course exclude cases when language is simply and obviously
           | unsuitable for the domain. Writing low level video codec in
           | Python is definitely not the best idea. Quality of the
           | programmers on the other hand matters more.
        
             | scottjg wrote:
             | Paul is famous for his essay about Lisp - arguing that his
             | startup beat other startups because Lisp is such a better
             | language than C++ or Java which his competitors were using.
             | 
             | Unclear to me if this is really the meaningful reason that
             | Paul's company succeeded (I'd say obsession with
             | programming languages can be a counter-indicator for
             | productivity), but it clearly resonated with a lot of
             | people since that essay is arguably the onramp into Paul's
             | fame. A lot of programmers read that essay back in 2001.
             | His popularity as an investor who understood engineers
             | arguably catapulted YCombinator
        
               | FpUser wrote:
               | I think that whatever his achievements, those are the
               | result of his business savvy and being able to execute.
               | Praising Lisp just shows that it is his favorite language
               | and he's using his clout to promote it, nothing is wrong
               | about it of course. But as I've already said I believe
               | that he could've used plenty of other languages with
               | exactly the same outcome business wise.
        
               | bcrosby95 wrote:
               | I don't think he was obsessed with languages. He picked
               | the one he knew best.
               | 
               | I also think the whole blub thing becomes less and less
               | relevant with every passing day. Every language has
               | evolved significantly over the last 20 years - when he
               | wrote that article - much less the last 26 years since he
               | started viaweb.
               | 
               | I personally prefer FP languages. I don't think they give
               | me magical superpowers... okay, well, maybe BEAM
               | languages in certain circumstances. But I also know
               | people that work magic with C and do things I could never
               | dream of.
        
             | [deleted]
        
           | AnimalMuppet wrote:
           | In fact, Go was _designed_ to enable average programmers to
           | be productive on large systems. You might call that  "Blub";
           | I don't.
           | 
           | In fact, I claim that Paul Graham is completely wrong in that
           | essay. To see why, think about Lisp and Haskell. When Lisp
           | users look at Haskell, they know they're looking down, and
           | they know why. "How can you get anything done in Haskell? It
           | doesn't even have macros." But when Haskell users look at
           | Lisp, they _also_ know that they 're looking down, and they
           | know why. "How can you get anything done in Lisp? It doesn't
           | even have a decent type system."
           | 
           | This situation - both languages certain that they're looking
           | down when they look at each other - shows the problem in
           | Graham's analysis. He assumes that languages can be placed on
           | a one-dimensional axis labeled "power". They can't be, and
           | the Lisp/Haskell issue proves it. That renders Graham's
           | analysis invalid.
           | 
           | Instead, it might be better to think of languages as living
           | in a multi-dimensional tree. Think of the program you're
           | trying to write as having a vector in that multi-dimensional
           | space. (Not so much the program itself, but what it makes it
           | difficult to write.) Pick the language that extends the
           | farthest in the direction of the vector defined by the
           | program.
           | 
           | What Go did is recognize that "ability to get a large team of
           | average programmers to maintain and extend a large codebase
           | for decades" was one of the dimensions of the space. That
           | makes it "Blub" by Graham's definition, but I don't think
           | that's meaningful. Instead, if that's what your program
           | needs, _pick a language that does that_.
        
         | apazzolini wrote:
         | Here's a blog series that you'll likely find enlightening:
         | https://jesseduffield.com/Gos-Shortcomings-1/
        
           | philosopher1234 wrote:
           | I did not find this enlightening (and I've read it before).
           | This criticism is fixated on what I would consider minor
           | annoyances in using Go, and doesn't explain why they're such
           | a big deal.
        
         | [deleted]
        
           | [deleted]
        
         | marwatk wrote:
         | I have an irrational dislike of go because for every X it's
         | missing the community's answer is "you don't need X" (until
         | they decide you do). Package management, generics, sum types,
         | decent error handling, etc. It's an arrogant approach that rubs
         | me the wrong way. It reminds me of "You're holding it wrong"
         | and seems ingrained in the go ethos.
         | 
         | That's not to say I'm not productive in go, but I could be
         | vastly more productive.
        
           | twsted wrote:
           | If I rethink about how long I was kept away from go by its
           | error handling and then I fell in love with it...
        
         | oconnor663 wrote:
         | > So, for those of you who are willing to explore the part of
         | this that goes beyond a simple rational analysis and criticism
         | of language design, whats bugging you?
         | 
         | I coded primarily in Go at work for several years, although
         | that was several years ago. I understand that package
         | management and now generics have changed in major ways since
         | then. But at the risk of being out of date, here are some
         | language-level complaints I had at the time, focusing less on
         | convenience/taste and more on things that I felt made it harder
         | to write correct code:
         | 
         | - Nil pointers. Go doesn't have any built-in way of
         | distinguishing between pointers that can be nil and pointers
         | that can't.
         | 
         | - Two kinds of nil. Go distinguishes between typed and untyped
         | nil pointers.
         | 
         | - Automatic zero-initialization of omitted fields. Adding a new
         | field to a struct has a tendency to make existing callsites
         | incorrect without producing any compiler errors.
         | 
         | - Mixing declaration and assignment on the left side of the :=
         | operator. Copy-pasting a line from an outer scope to an inner
         | one silently changes assignments into shadowing declarations.
         | 
         | - Calling append() without capturing its return value is always
         | wrong. This mistake is easy for linters to catch in simple
         | cases, but aliasing creates more complicated cases.
         | 
         | - It's easy to make an implicit temporary copiy of an object
         | without realizing it, like by using a value method receiver or
         | by looping over a slice of values.
         | 
         | These are examples of things that made me feel like I was
         | "fighting the language" to try to write correct code. I'd
         | appreciate feedback about any of these that might have changed
         | in the last few years.
        
           | kaba0 wrote:
           | And the stupidest of all: defer is function-scoped, not
           | block.
        
             | oconnor663 wrote:
             | I don't like calling any of these things stupid. They're
             | tradeoffs, and I can respect why they were made.
        
               | kaba0 wrote:
               | I would agree with you in the general case, but I yet to
               | hear any sort of sane explanation for why it is the way -
               | and it is not like a typical tradeoff where something
               | arguably worse would have been chosen otherwise, it is
               | just a small semantic change to a keyword.
               | 
               | But its effect is huge, e.g. the prototypical usage of
               | the keyword would be to unlock mutexes, but it is simply
               | a huge footgun, see:
               | https://news.ycombinator.com/item?id=30253426
        
         | gerbilly wrote:
         | > I would like to understand a bit more about where a lot of
         | the Go criticism comes from.
         | 
         | Go is really s souped up version of C. It's a design rooted in
         | the 70s with some fixes to make it a good language for writing
         | small networked apps.
         | 
         | Insofar as that goes1, the language is fine.
         | 
         | However the creators of Go responded to critiques of the
         | language in a patronizing manner and talked down to their own
         | programming community at Google as being unable to handle
         | complex languages.
         | 
         | Basically the Go community got the exchange off on the wrong
         | foot. Personally, I sense egos were at stake. They created a
         | language which is simple by design, but then still wanted to
         | claim a sort of opinionated superiority for it.
         | 
         | If they'd said, "oh go is just a simple little language we
         | enjoy using for such and such, perhaps you will too" then
         | people who don't like Go wouldn't have felt provoked.
         | 
         | 1: Pun not intended.
        
           | ainar-g wrote:
           | > However the creators of Go responded to critiques of the
           | language in a patronizing manner and talked down to their own
           | programming community at Google as being unable to handle
           | complex languages.
           | 
           | Can you provide examples of that? Because the closest thing I
           | can remember is Go creators saying that C++ had too many
           | features interacting in weird ways, and that they wanted to
           | avoid that. Which is a perfectly normal design goal.
        
             | MAGZine wrote:
             | look at most threads when people ask about quirky aspects
             | of go, such as:
             | 
             | a) why are there such short variable names, such that you
             | see calls like b.c.d.Method() all of the time?
             | 
             | b) why is there no Set type?
             | 
             | c) why is date/time encoding/decoding inconsistent in json
             | marshaling/unmarshaling (versus other types)?
        
             | ______-_-______ wrote:
             | Here's the original Rob Pike quote:
             | 
             | > The key point here is our programmers are Googlers,
             | they're not researchers. They're typically, fairly young,
             | fresh out of school, probably learned Java, maybe learned C
             | or C++, probably learned Python. They're not capable of
             | understanding a brilliant language but we want to use them
             | to build good software. So, the language that we give them
             | has to be easy for them to understand and easy to adopt.
             | 
             | The source seems to be MSDN, but the link has bit-rotted.
             | https://channel9.msdn.com/Events/Lang-NEXT/Lang-
             | NEXT-2014/Fr...
             | 
             | This attitude I think is the reason most experienced
             | deveploers I've worked with are put off by the language.
             | You don't have to be a "researcher" to understand sum types
             | or generics. There's a large part of the industry that
             | thinks we should limit ourselves to concepts that can be
             | understood by a beginner, and I think it's holding the
             | industry back. I can't think of another industry where
             | people think this way.
        
               | tharne wrote:
               | > There's a large part of the industry that thinks we
               | should limit ourselves to concepts that can be understood
               | by a beginner
               | 
               | I've never fully understood this weird obsession either.
               | You'd never hear a group of master craftsmen like
               | plumbers or masons talking about making their tools and
               | trade more "beginner friendly". They naturally expect
               | beginners to learn the trade and eventually become
               | masters themselves.
               | 
               | The cynic in me thinks it's large corporations that are
               | pushing the whole "beginner friendly" narrative as a way
               | to keep employees both 1) lower-skilled and 2)
               | productive. If you help beginners develop into
               | intermediate and then advanced programmers, guess what?
               | You have to pay them more.
        
               | ainar-g wrote:
               | > If you help beginners develop into intermediate and
               | then advanced programmers, guess what? You have to pay
               | them more.
               | 
               | That doesn't seem like a good argument with regards to Go
               | specifically, since Go is among the most high-paying
               | technologies, at least according to Stack Overflow
               | surveys[1]. At the same level as "LISP" (which Lisp is
               | it, StackOverflow?) and only slightly below Rust and
               | Scala, both of which are way more complex languages.
               | 
               | [1]:
               | https://insights.stackoverflow.com/survey/2021#section-
               | top-p...
        
               | tharne wrote:
               | > Go is among the most high-paying technologies
               | 
               | I like go just fine, and I'm learning it as we speak. But
               | I think the high pay scale has more to do with *where*
               | it's being used more than anything else.
               | 
               | Go is very popular in SV, whereas most fortune 500 and
               | other legacy companies are java world.
               | 
               | My issue is more with this current obsession that
               | everything _must_ be beginner friendly. The fact is
               | beginners don 't stay beginners very long, so it's a dumb
               | group to optimize for.
        
               | matwood wrote:
               | I don't think this is a very good analogy. The craftsmen
               | I know use basic, simple tools that work well. They just
               | handle them masterfully. The more complex tools are often
               | for beginners who need the hand holding.
        
               | ainar-g wrote:
               | That seems like a pragmatic and honest way of looking at
               | software engineering, consistent with Russ Cox's later
               | thoughts on the difference between programming and
               | software engineering[1]. It sounds to me less like "this
               | is a language for beginners and underperformers" and more
               | like "this is a language using which large teams of
               | programmers with varying levels of experience can be
               | productive together".
               | 
               | > This attitude I think is the reason most experienced
               | deveploers I've worked with are put off by the language.
               | 
               | This is not my experience. Of the six team leads with
               | whom I've discussed the language (after they've had some
               | experience with it) only one was put off by it. The rest
               | were either glad that "something simpler is finally here"
               | or were of the opinion that Go is "just another
               | language".
               | 
               | (Interestingly enough, the one person who was not
               | impressed was a big fan of purely functional programming,
               | while all others were C++/Java/Ruby kind of people. Which
               | is consistent with my own personal observation that fans
               | of purely functional languages tend to dislike Go, for
               | the most part.)
               | 
               | [1]: https://research.swtch.com/vgo-eng
        
               | Zababa wrote:
               | > Which is consistent with my own personal observation
               | that fans of purely functional languages tend to dislike
               | Go, for the most part.)
               | 
               | It's not only your personal observation (though I would
               | remove the "purely" from "purely functional languages). A
               | good indication of that: on the Go 2020 survey, the 6
               | most popular responses to "Which critical language
               | features do you need that are no available in Go?" are
               | features that functional programming languages have. All
               | of these features are in ML and its descendants (SML,
               | OCaml, Haskell, Scala, etc).
               | 
               | The graph:
               | https://go.dev/blog/survey2020/missing_features.svg
               | 
               | The article: https://go.dev/blog/survey2020-results
        
               | thinkharderdev wrote:
               | As a fan of pure functional programming who very much
               | dislikes Go, I can vouch for this statement. But in the
               | spirit of giving credit where due one thing that the pure
               | functional crowd can learn from Go is the value in making
               | really good tooling and really try to genuinely make easy
               | things easy.
        
             | gerbilly wrote:
             | Sorry can't find any since google results seem to get worse
             | year over year.
             | 
             | Basically I gleaned this impression from the go message
             | groups more than 5 years ago.
             | 
             | Go is pretty nice, but IMHO, it's no masterpiece.
             | 
             | There's a reason we keep copying C like syntax, and it's
             | not just familiarity.
             | 
             | C could be criticized on many points, but in my opinion it
             | was a brilliant case of language design: Only 30 keywords,
             | the stdllib was a separate thing (not common at the time),
             | great as a systems programming language.
             | 
             | If you think of C of the 1970s as a sort of souped up macro
             | assembler, you're not far from the truth, and it was wildly
             | successful, also, because of what it left out.
             | 
             | Go might have had similar ambitions, but the execution was
             | not thought out as well. If you want to design a truly
             | great language, it turns out it's not enough to merely
             | leave things out.
             | 
             | I got the sense that the Go people wanted to be taken
             | seriously on the same level as great achievements like C
             | and UNIX, but the creators quickly saw through the incoming
             | critiques that they hadn't pulled this off.
             | 
             | You know when you create something and then receive
             | criticism? If the criticism is clearly wrong or due to a
             | misunderstanding, you're not upset about it typically. You
             | explain that the misunderstanding, and typically the person
             | critiquing says, "ah ok..." and moves on.
             | 
             | But the critiques which really get to you are usually the
             | ones which you know deep down are right. I think maybe this
             | is why the creators of Go seemed so touchy about it.
             | 
             | EDIT: And for the record I program in Java and Rust mostly,
             | a bit of Python too. I hate C++ (a sprawling mess) and also
             | don't give a crap about Haskell or monads.
        
               | scns wrote:
               | > I got the sense that the Go people wanted to be taken
               | seriously on the same level as great achievements like C
               | and UNIX, but the creators quickly saw through the
               | incoming critiques that they hadn't pulled this off.
               | 
               | One of the creators of Go is Ken Thompson.
               | 
               | "I did the first of two or three versions of UNIX all
               | alone. And Dennis became an evangelist. Then there was a
               | rewrite in a higher-level language that would come to be
               | called C. He worked mostly on the language and on the I/O
               | system, and I worked on all the rest of the operating
               | system."
        
           | zozbot234 wrote:
           | Go has a lot more in common with Alef or Limbo than it does
           | with C, but close enough. It feels like it's been forever
           | stuck in the early 1990s, and now that it's gotten generics
           | it has perhaps reached the late 1990s.
        
           | ModernMech wrote:
           | > Basically the Go community got the exchange off on the
           | wrong foot.
           | 
           | Indeed. Then there was that whole controversy over the naming
           | collision with the Go! language. Basically there's an
           | unspoken etiquette in the PL community that there should be
           | zero name conflicts between languages, as there are enough
           | good names out there, it really shouldn't be an issue. The
           | Go! language had been around for a long time, and I realize
           | it was an obscure, little known language, but that's true for
           | 99% of languages out there. So the idea that Google can just
           | invent a language out of the blue with the same name as
           | yours, after you've been using the name for a decade, and
           | then just use their size and clout to essentially destroy
           | your language is.... well that's unsettling to people in the
           | PL community. The way they handled the situation didn't
           | exactly win over hearts:                 The naming
           | similarity is unfortunate. However, there are many computing
           | products and services named Go. In the 11 months since our
           | release, there has been minimal confusion of the two
           | languages, so we are closing this issue. Status changed to
           | Unfortunate.
           | 
           | https://github.com/golang/go/issues/9#issuecomment-66047478
           | 
           | Basically a sad trombone. The image of Go has never recovered
           | in my eye.
        
           | mseepgood wrote:
           | > Go is really s souped up version of C.
           | 
           | But with generics, methods and interfaces, proper strings,
           | maps etc., first-class functions, built-in concurrency, a
           | module system, automatic memory management, a well-rounded
           | standard library and so so so much more.
        
             | jhgb wrote:
             | Not even that -- it's a souped-up version of _Oberon_ with
             | these features. (Although of course, out of those, Oberon
             | had already had a module system and automatic memory
             | management.)
        
               | mseepgood wrote:
               | That's a good thing.
        
           | philosopher1234 wrote:
           | I'm glad you brought this up because I agree Rob pikes quote
           | about go being simple for average programmers has been very
           | provocative, because it's been interpreted as "Google devs
           | are too stupid for a good language like Haskell, so if you
           | use go it's because you're stupid too".
           | 
           | I'm partial to a different interpretation, that's more like
           | "go doesn't require as much thinking as Haskell, so you can
           | use your thinking for the problem you're trying to solve
           | instead of the language".
           | 
           | With that interpretation, go is better not just for stupid
           | programmers, but even for the smartest programmers.
        
             | ______-_-______ wrote:
             | That line of thinking only works up to a certain point. I
             | could say assembly language is simpler, now you don't have
             | to think about functions or basic blocks, you can save your
             | thinking for the problem you're trying to solve! But
             | sometimes pushing complexity into the language instead of
             | onto the users is the better way to go. Higher-level
             | abstractions make things easier. I would rather spend my
             | thought cycles on the business problem, than on
             | reimplementing sum types, or casting interface{}
             | everywhere, or propagating errors by hand.
        
               | philosopher1234 wrote:
               | Certainly, whether or not go has made the right trade
               | offs on simplicity is arguable. I'm not certain whether
               | those features you mentioned would be worth adding to the
               | language or not, but I do know that my experience
               | interacting with Go code has been much easier than my
               | experience interacting with Java code. Haskell & Rust
               | have been fun for me to play with, but they were also
               | harder for me to work with.
               | 
               | Anyways, I can't give the final word on this question,
               | but those are my two cents.
        
             | tharne wrote:
             | > I'm partial to a different interpretation, that's more
             | like "go doesn't require as much thinking as Haskell, so
             | you can use your thinking for the problem you're trying to
             | solve instead of the language".
             | 
             | I think you're being too charitable here. Rob Pike is a
             | very smart and articulate guy. If he had wanted to say "go
             | doesn't require as much thinking as Haskell, so you can use
             | your thinking for the problem you're trying to solve
             | instead of the language", then he would have. Instead he
             | took a dig at google employees. Make of that what you will,
             | but I don't think it's case of him mean anything other than
             | exactly what he said.
        
               | philosopher1234 wrote:
               | How you'd like to understand him is up to you, but even
               | if he does think we're all idiots, I think my point
               | stands.
        
             | [deleted]
        
             | codr7 wrote:
             | The real problem is designing tools for people who are not
             | as smart.
             | 
             | Because it's not that simple, and no one likes being judged
             | and talked down to.
        
         | Zababa wrote:
         | > I would like to understand a bit more about where a lot of
         | the Go criticism comes from. Of course some amount of it comes
         | from direct frustrations people have with the language design,
         | but I suspect that doesn't account for all of it. It seems to
         | me that the intensity with which some people fixated on the
         | absence of generics cannot be explained just by frustration
         | with writing non-generic code, which by all accounts was
         | annoying but not overwhelmingly so.
         | 
         | > In any case, it's something I've been trying to figure out
         | for a while and I don't think I have a complete explanation
         | still. Curious to see what others think.
         | 
         | Couldn't the same be said for every programming language, ever?
         | People often spend more energy complaining relative to the pain
         | that they went through, I don't think there is anything
         | specific about to Go about this. Just look at every discussion
         | about C, C++, Java, JavaScript, Python, Ruby or even better,
         | PHP.
        
         | icholy wrote:
         | People are upset that their favourite language didn't get as
         | popular as Go.
        
           | echelon wrote:
           | Counter point: Generics make me far more inclined to use Go
           | regularly. If error handling is improved to be safer and more
           | ergonomic, it'll be incredibly compelling for me.
           | 
           | Generics were the biggest feature keeping me from using the
           | language, and now that's a done deal. I'm excited.
        
             | icholy wrote:
             | If you consider the adoption rate, it's pretty clear that
             | the people who avoid Go because of <insert missing feature>
             | are a vocal minority.
        
               | throwaway894345 wrote:
               | Personally I considered it something of a feature that Go
               | repelled people who prioritized "writing in their
               | personal style" or "showcasing their powers of
               | abstraction" above all other concerns. The result was
               | standard, readable, boring code which made Go a _very_
               | productive tool.
        
               | echelon wrote:
               | Well, I can only speak for myself :)
        
               | mcronce wrote:
               | While true, that doesn't really change the situation for
               | the individuals who require <missing feature>
        
               | throwaway894345 wrote:
               | No one meaningfully "requires generics", people are just
               | reluctant to set their ego aside and learn a different
               | approach. Some _use cases_ may _benefit_ from generics,
               | but even then  "require" is too strong.
        
               | mcronce wrote:
               | Considering the alternative is often either "copy and
               | paste a bunch of code with a type changed in a bunch of
               | places and commit the result" or "vtable dynamic
               | dispatch", it's perfectly fair for a person to say that
               | they require that feature.
               | 
               | Generics also aren't the only useful feature that Go
               | lacks (or, as of today, _lacked_ ).
        
               | throwaway894345 wrote:
               | You still don't "require generics", you might _require
               | more performance_ than idiomatic Go offers, but in this
               | case you 're also excluding everything slower than
               | C/C++/Rust irrespective of whether or not the language
               | supports generics.
               | 
               | > Generics also aren't the only useful feature that Go
               | lacks (or, as of today, lacked).
               | 
               | Agreed, but it's foolish to frame language debates purely
               | around the presence or absence of useful features. Many
               | languages have _too many features_ including a great many
               | _misfeatures_ which degrades the overall experience, and
               | your analysis doesn 't account for that. Further, there
               | are costs associated with things like generics which your
               | analysis similarly ignores. Further still, it ignores
               | things like tooling, ecosystem, learning curve, etc. This
               | is how you end up with C++.
        
               | mcronce wrote:
               | > You still don't "require generics", you might require
               | more performance than idiomatic Go offers, but in this
               | case you're also excluding everything slower than
               | C/C++/Rust irrespective of whether or not the language
               | supports generics.
               | 
               | Performance only drives one of the two alternatives.
               | 
               | > Agreed, but it's foolish to frame language debates
               | purely around the presence or absence of useful features.
               | Many languages have too many features including a great
               | many misfeatures which degrades the overall experience,
               | and your analysis doesn't account for that. Further,
               | there are costs associated with things like generics
               | which your analysis similarly ignores. Further still, it
               | ignores things like tooling, ecosystem, learning curve,
               | etc. This is how you end up with C++.
               | 
               | This isn't an analysis. It's a counterpoint to a single
               | individual on a social media website.
               | 
               | Go's ecosystem and learning curve are great. The best
               | thing I can possibly say about its tooling is "it's
               | better than C and C++". Seriously, _how many_ dependency
               | management paradigms have we gone through so far, and the
               | best thing we can come up with is `go mod`?
        
               | lolinder wrote:
               | Honestly, one of the biggest things that drives me away
               | from Go isn't the lack of features, it's this
               | condescending attitude that comes from so many people who
               | espouse Go. I don't need to invest in a language whose
               | community is so hostile.
               | 
               | If you wanted to be persuasive or helpful, you could try
               | explaining what the other approaches to work around
               | lacking generics might _be_ , rather than just insulting
               | people for being unable to figure out on their own how to
               | avoid copy/paste spamming their codebase.
        
               | throwaway894345 wrote:
               | > Honestly, one of the biggest things that drives me away
               | from Go isn't the lack of features, it's this
               | condescending attitude that comes from so many people who
               | espouse Go.
               | 
               | I could say the same about many of Go's critics, but I
               | don't because that wouldn't be constructive. Rather than
               | taking undue offense at my comment, why not articulate a
               | counterexample to prove that there are valid reasons why
               | a person (rather than a use case) might _require
               | generics_?
               | 
               | > If you wanted to be persuasive or helpful, you could
               | try explaining what the other approaches to work around
               | lacking generics might be, rather than just insulting
               | people for being unable to figure out on their own how to
               | avoid copy/paste spamming their codebase.
               | 
               | Because these are already well-understood and have been
               | debated to death. Instead of
               | .map().filter().flat_map().reduce() you use a simple for
               | loop. Instead of `LinkedList<ItemType>` you use `type
               | List struct { Item ItemType; Next _List }`. The thing
               | that we generally_ aren't* agreed on is whether those
               | extra characters are actually the end of the world versus
               | the benefits associated with simpler, more concrete, more
               | standard code.
               | 
               | Anyway, I wasn't "insulting" anyone, I was describing Go
               | critics' objections in roughly their own terms (i.e., in
               | so many conversations I've had with Go critics esp over
               | generics, the conversation eventually terminates at some
               | variation of "Go forces me to think about programming
               | differently than I'm used to").
        
               | mcronce wrote:
               | > simpler, more concrete, more standard code.
               | 
               | All three of these things are subjective.
               | 
               | > in so many conversations I've had with Go critics esp
               | over generics, the conversation eventually terminates at
               | some variation of "Go forces me to think about
               | programming differently than I'm used to"
               | 
               | At some sufficiently large number of people, you need to
               | acknowledge that how they think isn't wrong, the language
               | is.
        
               | throwaway894345 wrote:
               | > All three of these things are subjective.
               | 
               | Not really. They aren't formally defined, but there's
               | pretty wide consensus even among Go detractors about
               | these qualities.
               | 
               | > At some sufficiently large number of people, you need
               | to acknowledge that how they think isn't wrong, the
               | language is.
               | 
               | Not when there are plenty of people willing to think
               | differently and reap the benefits.
        
               | philosopher1234 wrote:
               | >At some sufficiently large number of people, you need to
               | acknowledge that how they think isn't wrong, the language
               | is.
               | 
               | This justifies anything popular, including things that
               | are now universally seen as bad, but once were popular.
        
               | lolinder wrote:
               | Can you point me to a survey that shows that a majority
               | of developers would like to try Go? If not, how can you
               | be so sure that those who avoid it because of <insert
               | missing feature> are a minority?
               | 
               | As a counterpoint, here's a survey that suggests that
               | only 14.54% of developers have any interest in learning
               | Go. How many of those who don't are turned off by lack of
               | features? I don't know, but I'm not sure how you could
               | either.
               | 
               | https://insights.stackoverflow.com/survey/2021#most-
               | loved-dr...
        
           | pjmlp wrote:
           | Go needs to catch up with 25 years of Java, 20 of C#, and 40
           | of C++ regarding industry adoption.
           | 
           | Not worried, just pleased it is finally catching up with
           | modern times.
        
         | s3graham wrote:
         | The silly things that bothered me the last time I tried to use
         | it: 1) lame un-opininated formatter (no line wrapping); 2)
         | obtuse-but-mandatory directory structure for modules once you
         | move beyond a single file (maybe this has improved?); 3)
         | embarrassingly large binaries.
        
         | beltsazar wrote:
         | > Generics will be helpful for some, I'm sure, but my reading
         | of the winds is that people will find other idiosyncracies of
         | Go to latch onto and complain about. It seems to me the next
         | object of hatred is the lack of sum types.
         | 
         | Lacking generics is not in the same league as lacking sum types
         | or other features. Only a few major static languages have sum
         | types, whereas most major static languages have generics.
        
         | freedomben wrote:
         | I'm not the target market for your question, but I stopped
         | using Go mainly because I felt constrained. I prefer functional
         | programming style and that was very difficult in Go. More than
         | that, I hated having the language dictate to me where my code
         | had to live (this has since been fixed). I also disliked the
         | lack of a package manager (also since fixed). I do dislike the
         | verbosity of Go programs (some of which is forced by the
         | language, other of which is self-inflicted by devs writing very
         | long functions), although this is more of a style choice, and
         | style is something that you can get used to.
         | 
         | I don't dislike Go though, and I still use it occasionally. I
         | love the go formatter, and I like the built in channels
         | (although now that I've experienced Elixir/Erlang I think the
         | actor model is pretty great).
         | 
         | I think of it as a flavor of ice cream: some people will like
         | it, others won't. Even if I hated Go, I still believe that the
         | diversity in languages is a good thing and I have yet to see a
         | language that didn't contribute to overall progress.
        
           | throwaway894345 wrote:
           | > I'm not the target market for your question, but I stopped
           | using Go mainly because I felt constrained. I prefer
           | functional programming style and that was very difficult in
           | Go.
           | 
           | Yeah, Go is opinionated. I like functional programming style
           | too (because I like being abstract), but it's hard for me to
           | deny that it's easier for people to read code which is more
           | concrete and standardized (fewer ways to express the same
           | idea) even if there is more boilerplate.
           | 
           | > More than that, I hated having the language dictate to me
           | where my code had to live (this has since been fixed). I also
           | disliked the lack of a package manager (also since fixed).
           | 
           | These things have been fixed for a long time. It sounds like
           | you tried Go when it was quite young.
           | 
           | > I think of it as a flavor of ice cream: some people will
           | like it, others won't.
           | 
           | I agree. To expound on that, I'll also posit that people have
           | different goals in choosing a programming language. Some
           | people want a language that makes them feel clever / express
           | themselves aesthetically and others want a ruggedly practical
           | language / Get Shit Done (I definitely fall into both camps).
           | Go is squarely in the latter camp.
        
             | freedomben wrote:
             | Yes absolutely, I did most of my Go programming in the 1.5
             | days, so (as I mentioned) some of my dislikes have been
             | fixed.
             | 
             | > _but it 's hard for me to deny that it's easier for
             | people to read code which is more concrete and standardized
             | (fewer ways to express the same idea) even if there is more
             | boilerplate._
             | 
             | Yes, absolutely agree. When working on a team, especially a
             | big team, that's a huge benefit that shouldn't be
             | overlooked.
        
         | tacotacotaco wrote:
         | I like the simplicity of the language. What I did not like was
         | the complete denial of functional patterns for problem solving.
         | The language has first class functions but language's "best
         | practices" and the core library are imperative and all 3rd
         | party libraries (rightly) follow suit.
         | 
         | I appreciate that the language designers had a specific vision
         | for their language. I have much respect for them. They have a
         | lot of experience and expertise. I prefer functional patterns
         | so I decided to discontinue go and learn a different language.
        
           | synergy20 wrote:
           | 'discontinue go and learn a different language', which is
           | what?
           | 
           | there are not many 'better' languages to pick these days, all
           | languages have pros and cons, even Rust won't save the world.
        
       | jadbox wrote:
       | Is there a go-to implementation of typed map/reduce/filter with
       | 1.18?
        
         | maxekman wrote:
         | https://pkg.go.dev/golang.org/x/exp/maps
         | https://pkg.go.dev/golang.org/x/exp/slices
         | https://pkg.go.dev/golang.org/x/exp/constraints
        
         | frenchie4111 wrote:
         | Someone started a lodash style stdlib replacement:
         | https://github.com/samber/lo
        
       | fpoling wrote:
       | For me the most puzzling aspect of Go is channels. Ada tried CSP
       | (Concurrent Sequential Processes that Go channels are based on)
       | in eighties and people quickly realized that it lead to bad
       | performance and was unsuitable for a lot of useful cases. So Ada
       | got standard mutexes and signals.
       | 
       | So why CSP which does not allow to implement priority delivery or
       | multicasting and makes cancelling much harder compared with
       | normal polymorphic message queue per thread? Moreover, Go
       | crippled CSP even further as one cannot select on channel and
       | file descriptor.
       | 
       | Fortunately Go does provide mutexes and signals so one can ignore
       | channels unless required by Go API. Still without proper sum
       | types polymorphic and type-safe message queues are not possible.
        
         | pkulak wrote:
         | I can never seem to understand why a GCed language has
         | pointers, and makes you memorize when to use stack vs heap.
        
           | hnov wrote:
           | I think it's at least partially about value vs (mutable)
           | reference semantics in Golang's case and the hope is that the
           | compiler will know to whether heap or stack allocate based on
           | escape analysis.
        
           | Laremere wrote:
           | Go uses escape analysis to ensure memory safety of pointers.
           | Taking a reference of a local variable means it might end up
           | on the heap, and calling new might allocate on the stack. It
           | all depends on if Go can determine that the lifetime of the
           | pointers is less than the stack frame.
           | 
           | It's good if you don't want to care about those details, it's
           | bad if you really care about those details for performance
           | reasons.
        
           | foldr wrote:
           | >and makes you memorize when to use stack vs heap
           | 
           | You don't have to think about stack vs. heap allocation in Go
           | unless you're writing performance sensitive code. You could
           | pretend that Go heap allocates everything and still read and
           | write Go code without any problems.
        
           | mftb wrote:
           | It's pretty straightforward, knowing when to use the stack vs
           | heap can improve your performance. Having both paradigms
           | available in the language means you can start out relying on
           | the GC for everything. Later when you're ready, you can look
           | to make more intelligent use of the stack.
        
         | Zalastax wrote:
         | You may find my MsC thesis, link in profile, interesting! If I
         | remember my writing correctly, I have similar reflections on
         | CSP.
        
         | zozbot234 wrote:
         | Go has shared memory and mutexes, but using them means giving
         | up on memory safety because the whole rigmarole that Rust does
         | to preserve safety in concurrent code is totally missing in Go.
         | So that's a meaningful reason to stick to CSP - sure, it might
         | create easy deadlocks but at least it won't totally crash your
         | app with a potentially exploitable fault.
        
           | fpoling wrote:
           | Go could have provided message queues with priorities Erlang
           | style or something closer native solutions in
           | Linux/Max/Windows that are known to work. They are safe,
           | allows to avoid deadlocks just as channels and much more
           | flexible.
           | 
           | And with mutex one can build those as necessary, even if
           | interaction with channels is ugly.
        
         | coder543 wrote:
         | > Still without proper sum types polymorphic and type-safe
         | message queues are not possible.
         | 
         | This isn't really true.
         | 
         | You can define a channel where the message type is an
         | interface, and then you can use a type switch on the receiving
         | side to downcast that interface to various concrete message
         | types.
         | 
         | What you _can 't_ do without sum types is ensure that you don't
         | need a "catch-all" branch for if/when a value is sent down the
         | channel that isn't one of the concrete message types you
         | expect, but it will still be type safe and polymorphic.
        
         | avl999 wrote:
         | Avoid channels except for straight forward, producer-consumer
         | workflows. Use mutexes and other traditional concurrency
         | primitives for other stuff. Channels are a huge shotgun with
         | caveats.
        
           | gilgad13 wrote:
           | I agree, with the addition that closing an unbuffered `<-chan
           | struct{}` is a good way to do broadcast notifications (a. la.
           | the context package).
           | 
           | As evidence that channels should be used rarely, and only in
           | small scopes, consider the number of places chan is used in
           | the standard library.
        
       | mseepgood wrote:
       | Now Go has everything I need in a programming language!
        
         | drdaeman wrote:
         | Not for me. There is no ?: ternary operator. Having to write 6
         | additional lines of code for each tiny conditional sucks. It's
         | not frequent, I think I've only had a single case in a few
         | years where I had difficulty working around, but when it
         | happens - it's not fun.                 err := h(cond(x) ? f(x)
         | : g(x))
         | 
         | vs                 var temp T       if cond(x) {         temp =
         | f(x)       } else {         temp = g(x)       }       err :=
         | h(temp)
         | 
         | Hopefully, this can be improved with generics, e.g. now it
         | should be possible to create e.g. `func Coalesce (type T)
         | (...args T) T` function to simplify common scenarios.
        
           | ngrilly wrote:
           | If you only had a single case in a few years, then why would
           | you need a ternary operator? Your anecdotal data experience
           | is actually confirming their decision to leave this out of
           | the language.
        
           | Mawr wrote:
           | I agree that the latter version is too verbose, but if the
           | alternative is this:                 err := h(cond(x) ? f(x)
           | : g(x))
           | 
           | ... then I'd much rather stick with the verbosity. There's
           | way too much going on in a single line here.
           | 
           | I'd rather have if statements be expressions, with gofmt-
           | enforced line breaks:                 err := h(         if
           | cond(x) {           f(x)         } else {           g(x)
           | },       )
           | 
           | No unnecessary temp variables _and_ no stuffing everything
           | into one line.
        
           | crtc wrote:
           | This is by design:
           | https://go.dev/doc/faq#Does_Go_have_a_ternary_form
           | 
           | Ken Thompson added ?: to B / C and then he took it from us in
           | Go due to the wisdom he gathered in between.
        
             | RodgerTheGreat wrote:
             | > A language needs only one conditional control flow
             | construct.
             | 
             | And yet, Go has a switch statement.
        
               | MrDOS wrote:
               | Not only that, but despite all of the other syntactic
               | sugar Go is lacking (usually sorely, such as a "try"
               | error handler), the switch statement is really just an
               | "if" statement in disguise.                   var
               | someVar, anotherVar string         // ...         switch
               | {         case someVar == "whatever":
               | fmt.Println("Tell me how, exactly,")         case
               | anotherVar == "nope":             fmt.Println("this
               | compiles to a jump table?")         default:
               | fmt.Println("Spoiler: it doesn't.")         }
        
       | oxplot wrote:
       | When you hear most critics of Go (or any language for that
       | matter), they talk as if Go is merely an alternative syntax for
       | their favorite language. Of course they're bothered by lack of a
       | missing features and unfamiliar ways. As tired of an analogy as
       | it may be, programming languages are like natural languages.
       | Trying to learn Japanese by translating sentences, idioms and
       | proverbs from English word for word will only end in frustration
       | and confusion.
       | 
       | If you read the history of Go, the whole point behind its
       | creation (as with many others) was to start with a clean slate so
       | new norms and ways of doing things could form, in service of
       | large distributed teams and long term maintainability. Lack of
       | generics, as unrelated as it may seem, is actually the result of
       | the those and other goals. Specifically, Go authors avoided
       | complicating the language, runtime, and compiler early on and
       | thereby avoided negatively affecting long term maintainability of
       | both the language and the code written for it (v1 compatibility
       | promise) before having a good grasp of how generics should be
       | implemented in this new language or if it should be at all.
       | Copying the so called tried and tested implementations from
       | existing languages would make little sense as generics are so
       | intertwined with the rest of a language.
       | 
       | TL;DR approach learning programming languages like you would
       | approach learning a new natural language with the purpose of
       | living among its native speakers.
        
         | pie_flavor wrote:
         | Certainly a better take than 'I don't like generics, it's
         | somehow less complicated to downcast interface{} everywhere'.
         | It was very interesting reading the justification for not
         | having generic methods, and how that clashed with my assumption
         | of what generics should be, or for that matter what methods
         | should be. Go is the spiritual successor to C, IMO - for all
         | that people use it nowadays for its low-level capability,
         | people forget that its original purpose was to do what every
         | other language of its day did, but way, way more simply.
        
       | frenchie4111 wrote:
       | In celebration of generics release, I was playing around with
       | supporting Optionals via generics. If anyone's interested I am
       | happy to make this a real project
       | 
       | https://github.com/frenchie4111/go-generic-optional
        
         | daptaq wrote:
         | My main fear with the introduction of generics was the lack of
         | stdlib support. I know they want to play it safe and are
         | planning to change this in future versions, but the last thing
         | I want is that I have to download some github.com/foobar/...
         | library for every common sense generic type I might want to
         | use.
        
           | heavyset_go wrote:
           | Agree with this sentiment. It was a very good idea to bring
           | the `typing` module into the Python standard library versus
           | just relying on Mypy.
        
         | Mawr wrote:
         | type Optional[T any] struct {         value *T       }
         | 
         | Don't use a pointer - it's bad for performance.
         | func MakeOptional[T any](value *T) Optional[T] {
         | 
         | Use `New` instead - it's the idiomatic name for a constructor
         | in Go. Drop the `Optional` part - the module name suffices -
         | the caller will see: `opt.New`. Personally I just call the
         | module `optional`, I think it's clearer: `optional.New`.
         | func (o* Optional[T]) Unwrap() (T, error) {
         | 
         | 1. `Unwrap` reminds me of Rust's .Unwrap, which panics. Seems
         | confusing.
         | 
         | 2. There's no error here, the situation is equivalent to a
         | missing key in a map - it's enough to return a bool.
         | 
         | Here's my implementation so far: https://gist.github.com/Mawr-
         | BF2/0a60da26f66b82ee87b98b03336.... Only thing I'm not sure
         | about is whether the JSON serialization methods are necessary.
        
           | wtfishackernews wrote:
           | For json marshalling, I would defer to the underlying type's
           | marshalling if it's present, and return `null` otherwise.
        
             | shhsshs wrote:
             | I think this is appropriate in some cases but not others.
             | For example how does the JSON value distinguish between
             | `Some(null)` and `None`?
        
               | dialogbox wrote:
               | IMO using Optional type means the inner value must be not
               | null. And if it's Some(null), it should mean exactly same
               | as None.
        
           | morelisp wrote:
           | Whether a pointer is bad for performance in this case seems
           | hard to tell a priori. There are also performance advantages
           | if Optional packs nicely.
        
             | frenchie4111 wrote:
             | Agreed on performance being in the air. Tbh, I like the
             | non-pointer option because using a pointer was causing the
             | implementation to feel a bit weird. This cleans up a bit of
             | the handling that was annoying (for example in the old
             | implementation Make(&"something") didn't work because you
             | can't reference a constant without first making a variable.
        
             | Mawr wrote:
             | It is just an assumption on my part, I figure that the cost
             | of pointer chasing is generally going to outweigh any
             | disadvantages. It can also help enable optimizations, for
             | example slices and maps that do not contain pointers do not
             | get scanned by the GC ([1]).
             | 
             | [1]: https://github.com/golang/go/commit/85e7bee19f9f26dfca
             | 414b1e...
        
               | stingraycharles wrote:
               | I fully agree with your approach. The important thing is
               | that the user now has the choice to use a pointer or not:
               | they can always use a pointer to the optional if they
               | want to use pointers.
               | 
               | Pointers to pointers are generally something you try to
               | avoid if possible.
        
           | frenchie4111 wrote:
           | I love it. I will update the library to match some of your
           | suggestions.
           | 
           | I agree with peer comment that we should likely defer to the
           | original type for JSON serialization.
        
         | pharmakom wrote:
         | Optionals without do notation will be a bad time.
        
           | LAC-Tech wrote:
           | What's do notation?
           | 
           | I've used optionals in many languages, and this is the first
           | I've heard of it. What else do you really need except map
           | and... flatMap (aka `then` aka `and_then` aka `>>=` aka
           | `bind`).
        
         | mountainriver wrote:
         | Awesome work! I would love to see something like this make it
         | into the language
        
         | assbuttbuttass wrote:
         | This looks kind of cool, but I think there's no version of this
         | as a library that could be considered idiomatic(TM), after all
         | "a little copying is better than a little dependency"
         | 
         | https://go-proverbs.github.io/
        
       | honkycat wrote:
       | WOOO!
       | 
       | I have been using the RC at work lately, and I have to say: The
       | generics implementation is quite nice, and RUTHLESSLY slashes
       | boilerplate and copy-pasta.
       | 
       | This is going to turn Golang from "that one boilerplate-y
       | language without generics" into my favorite language.
       | 
       | I've been using the https://github.com/samber/lo library, and it
       | is very nice to be able to do "map/reduce/etc..." on golang
       | structs.
       | 
       | I would really enjoy a chaining library, and some tooling to make
       | type coersion a bit cleaner.
        
         | earthboundkid wrote:
         | I find that the function boilerplate of Go is too long because
         | there's no equivalent of an arrow func. I can't see those kind
         | of libraries taking off until there's an easier way to write a
         | closure.
        
         | edenlinger wrote:
         | I don't mean to disparage the wonderful work of the lo
         | developers but, this is in many ways what I feared generics
         | would bring. If you aren't going to lean into the simplicity
         | and single way of doing something, you are likely better served
         | in another language.
         | 
         | I am probably an old man yelling at clouds and I hope those who
         | like this style get tons of value from it. I just don't see the
         | benefit of trying to retrofit some of the behavior of other
         | perfectly useful languages into Go. JS/Java/C#/Python/Ruby is a
         | fine language. Let each of them have their strengths. I feel
         | like trying to bolt things together this way only serves to
         | take away what is special and valuable in Go.
         | 
         | I should probably shut up and just be happy lots of other
         | people are using a language I enjoy :)
        
           | honkycat wrote:
           | > If you aren't going to lean into the simplicity and single
           | way of doing something, you are likely better served in
           | another language.
           | 
           | Generics were widely asked for by the community for many
           | reasons, one of the main things being reducing boilerplate
           | and having basic polymorphic functionality that other
           | languages provide.
           | 
           | I'm not trying to disparage you but: You don't know who I am,
           | or my capabilities. Please don't be condescending to me and
           | assume I just "don't get it" or that I am too lazy to learn
           | the "go" way of doing things.
           | 
           | I am seeing that a lot in this comment section. You are
           | judging others and coming to conclusions because we like
           | something you do not like. I can totally understand your
           | perspective, because I also see the danger of introducing
           | more "power" into a language that was elegant and simple.
           | 
           | I respect your disagreement with introducing generics to
           | Golang. However, please extend us the courtesy of assuming we
           | are at least remotely competent.
        
           | kortex wrote:
           | > I don't mean to disparage the wonderful work of the lo
           | developers but, > this is in many ways what I feared generics
           | would bring.
           | 
           | What is, anything in particular about that "lo" library? Just
           | the way it uses generics, or moreso that it's yet another
           | library to learn to be effective? Can't argue with the
           | latter, but as far as the former goes, I think that looks
           | quite reasonable. It's very explicit, there's no magic going
           | on. I think there's definitely a bar for "so much abstraction
           | that it is discouraging to developers not into that sort of
           | thing", and IMHO that doesn't cross it. Monads, sure, that's
           | a tall order for many folks. But this is pretty tame.
           | 
           | But I am a fan of abstraction so I'm not the best judge.
        
             | morelisp wrote:
             | Efficient map/filter/reduce chaining basically requires JIT
             | to fuse the operations and/or a GC prepared to deal with
             | huge amounts garbage. In Go, filter(h, map(g, filter(f,
             | a))) will be immensely slower than the equivalent for loop.
        
               | kortex wrote:
               | Great point. Although, that sounds like a typical example
               | of "let's write it the ergonomic but less performant way
               | first, then profile and refactor as needed". That seems
               | very tractable for that sort of refactor, especially with
               | type safety.
               | 
               | Also I would not be surprised to see JIT-like behavior
               | from go tooling, first party or otherwise, if that sort
               | of approach takes off.
        
         | aston wrote:
         | You might like Go-Chainable:
         | https://github.com/neurocollective/go_chainable
        
       | akmittal wrote:
       | Hopefully generics will help make better libraries for Graphql.
       | Existing libraries resorted to code generation a lot.
        
         | naikrovek wrote:
         | > Existing libraries resorted to code generation a lot.
         | 
         | guess what generics is in a lot of languages? code generation!
         | the files just aren't saved to disk.
         | 
         | IIRC on a podcast I seem to recall hearing that it was
         | implemented this way for Go, at least for the prototype, and it
         | seems likely to me that it is also done this way in production,
         | but not with textual code.
        
           | uluyol wrote:
           | Go is not quite doing this level of expansion: https://github
           | .com/golang/proposal/blob/master/design/generi...
           | 
           | In particular, a single expansion is shared for all pointer
           | types.
        
           | akmittal wrote:
           | Thats like saying lets just write assembly because eventually
           | code will be converted to assembly.
           | 
           | As a developer now we dont have to bother about codegen.
        
             | BobbyJo wrote:
             | No exactly. Assembly is more like the generated code than
             | the generator code.
        
         | bogomipz wrote:
         | Interesting. I'm curious how code generation is/was used to
         | work around the language not having having support for
         | generics? Or was this something specific to Graphql?
        
           | scheme271 wrote:
           | The kubernetes api (more specifically the k8s apimachinery)
           | code uses codegen in order to create code so that you can
           | convert custom CRDs to go structures rather than working with
           | json. It's one of the more opaque bits of writing go code
           | that works with k8s.
        
           | akmittal wrote:
           | gqlgen is most popular for graphql and uses codegen. It seem
           | to be good but It felt not that easy to use coming from node
           | world(apollo-server).
           | 
           | There were bunch of libraries which helped with code
           | generation to work around generics. I don't think it was
           | specific to Graphql.
           | 
           | https://github.com/cheekybits/genny is one I have seen.
        
       | typical182 wrote:
       | There is also a new set of FAQs on generics:
       | 
       | https://go.dev/doc/faq#Type_Parameters
        
       | gnoack wrote:
       | The general excitement about generics on this thread makes me
       | uneasy.
       | 
       | Please keep in mind that generics are a pretty big hammer - they
       | can add a lot of complication if not used with caution. Only use
       | a language feature if you absolutely must.
        
         | s-video wrote:
         | The thing that worries me is people trying to reconstruct
         | features from other languages with generics. One of the things
         | I like about Go is that no matter whose code you're looking at,
         | it's almost certain that you're already familiar with any
         | feature you'll see, because the set of features is relatively
         | small.
        
         | HideousKojima wrote:
         | I see it the other way around, generics reduce complication and
         | allow for code that's a lot more elegant and simple than
         | without. It definitely adds complexity on the compiler side of
         | things, but using them in C#, TypeScript, and Java has been
         | only a plus. Unless you count that time I tried to do stuff
         | with generic interfaces in Entity Framework Core, but that was
         | EF Core's fault as opposed to generics's.
        
           | CraigJPerry wrote:
           | >> generics reduce complication
           | 
           | That goes against the definition of the word complication. To
           | complicate something is to combine and intertwine it with
           | other concerns. To fold them together is to complicate them.
           | 
           | To generify a function is to complicate it with the ability
           | to accept multiple types rather than just one.
           | 
           | There are totally great use cases for generics but all the
           | cases I've seen are in library code not in general
           | application programming which is where most developers spend
           | most of our time. But of course the shiny toy can be hard to
           | resist and so generics are often overused and abused.
        
             | stouset wrote:
             | As a general rule, if you're referencing the dictionary
             | definition of a word to make your point, you're just
             | playing semantic games.
             | 
             | You know what people also find complicated? Hundreds of
             | lines code being repeated with superficial edits because of
             | golang's lack of ability to abstract higher-level ideas.
             | It's a stupid toy example, but for a _very large number of
             | people_
             | nums.take(20).select(&:odd).reduce(&:+)
             | 
             | is less complicated than                   sum := 0
             | for i, v := range nums {             if i > 20 {
             | break;             }             if v % 2 == 1 {
             | continue;             }             sum += v;         }
             | 
             | The former is less complicated for those people (including
             | me) because it expresses high-level _intent_ rather than
             | low-level implementation. Multiplied over a large code-
             | base, the ability to express intent adds up to an enormous
             | saving in mental overhead rather quickly. You can always
             | drill down and focus on implementation where it matters,
             | but with golang there 's almost zero ability to separate a
             | program's detailed implementation from a high-level
             | description of what you're actually trying to accomplish.
             | 
             | The Ruby version of this is also less bug-prone (did you
             | spot the bug in the go example?). And it's also easier to
             | apply to new contexts: the former works automatically for
             | infinite enumerations.
        
               | cdelsolar wrote:
               | should be == 0?
               | 
               | I don't like the Ruby example myself.
        
           | tptacek wrote:
           | As with everything else, sometimes this is true, sometimes it
           | isn't. In languages with pervasive generics, figuring out how
           | things work can mean following several extraneous layers of
           | indirection as any opportunity to parameterize something is
           | always taken. But writing the same stupid loop to delete
           | something from a slice is also unclear and complicated. The
           | point isn't that generics are bad, just that they should be
           | used judiciously.
        
           | gnoack wrote:
           | ...and that time when people reinvented boolean expressions
           | and their combinatorics under the disguise of Predicate<T>
           | and Matcher<T>, making test errors hard to comprehend for
           | very little additional benefit. etc etc
           | 
           | There is also the problem that people don't generally have a
           | good grasp on how to use type bounds[1] correctly... I
           | believe Go avoids the worst of it through its simple type
           | system, but still... this complicates a language
           | significantly.
           | 
           | [1] https://docs.oracle.com/javase/tutorial/java/generics/bou
           | nde...
        
       | Shadonototra wrote:
       | Why not link the announcement? https://tip.golang.org/blog/go1.18
       | 
       | Who cares about the tag
       | 
       | What's up mods? @dang yo
        
       | [deleted]
        
       | exdsq wrote:
       | Aaaand now watch every projects abstraction increase tenfold
       | under the weight of generics
        
         | avl999 wrote:
         | Or an expectation of competence from developers and expecting
         | them to consider tradeoffs of their design- in other words
         | doing their damn jobs as opposed to the language baby sitting
         | them away from tools they might use incorrectly.
        
           | exdsq wrote:
           | There's nothing wrong with a language being strict with what
           | you can do to force good programming styles. An expectation
           | of competence is nice if you can afford it, but it's also
           | nice to have languages that mean you don't have to take that
           | risk. It's why I liked Go and why I disliked working in
           | Haskell. Look at Lisp - large teams get tied in knots because
           | of the freedom. Go was nice because it just stopped you doing
           | 'smart' things. Now it has generics you may as well use Rust
           | or something else.
        
         | kortex wrote:
         | Or put another way, 1/10th the surface area of code to write,
         | maintain, review, and bug check. And much less interface{}
         | abuse.
         | 
         | That's taking "tenfold" at face value. I don't see that
         | happening personally. The go community has enough of a nucleus
         | of devs with a certain mindset that I don't see crazy Haskell
         | levels of abstraction taking over. What I do see is more type
         | safety coming to interface dynamicism.
        
       | eatonphil wrote:
       | Regarding Windows: while this isn't on scoop yet I was able to
       | get it in Github Actions like so:                  curl -L -O
       | "https://go.dev/dl/go1.18.windows-amd64.zip"        unzip
       | go1.18.windows-amd64.zip        Join-Path $pwd "go\bin" >>
       | $Env:GITHUB_PATH
       | 
       | A request/suggestion for the Go team: include instructions for
       | how to use the Windows zip! It's not a big deal but I had to
       | figure it out by `ls`-ing around.
        
       | mikojan wrote:
       | I will forever miss old Go :-(
        
       | haolez wrote:
       | I hope open source Go code in the wild remains easy to read and
       | understand. Generics look cool, despite this possible downside.
        
         | rochak wrote:
         | I have already started having trouble understanding open source
         | code using generics. I can see the upsides of having generics,
         | but have lost the enthusiasm with which I used to browse Go
         | code. I am still a junior engineer, so maybe it will get better
         | with time.
        
           | dgb23 wrote:
           | Every abstraction tool will get misused, especially early on.
           | I bet the Go community will figure out how ways to mitigate
           | that in the long run, given it's culture around readability.
        
         | chabad360 wrote:
         | I've found generic code much easier to read once I started
         | playing with it myself. It might be worth implementing a
         | generic sorter (or some other easily generic construct) just to
         | get more familiar with the new syntax.
        
       | pjmlp wrote:
       | Finally generics support. Now another 10 years for proper enums.
       | 
       | Kidding, I always mentioned that CLU like would be good enough.
        
       | dgrr19 wrote:
       | I started a template library some time ago. It needs a bit of a
       | clean up, but for starters it's quite decent.
       | 
       | https://github.com/dgrr/gtl
        
       | morelisp wrote:
       | strings.Cut / bytes.Cut is really nice.
        
       | flippinburgers wrote:
       | Honestly I think this will make the overall programming
       | experience worse.
        
         | pie_flavor wrote:
         | Is it a worse programming experience to understand an esoteric
         | library's use of [T U], or to need to choose between codegen vs
         | interface{} for the most common use cases? The ability to
         | misuse a feature should not be understated, but I think people
         | have been jumping over the missing stair of interface{} for so
         | long that they've forgotten how much of an incredible pain it
         | is.
        
         | HideousKojima wrote:
         | In what way? Almost every other major language has them without
         | major issues.
         | 
         | Go devs saying generics are a bad thing reminds me of people in
         | Oregon freaking out over being allowed to pump their own gas
         | while the other 49 states have been doing that for decades.
        
       | justinsaccount wrote:
       | Generics is the big news, but the fuzzing support is amazing too.
       | I added a fuzz test to an app I have in about 5 minutes. It was
       | no harder than adding a normal test.
       | 
       | I expect to see a huge boon in users of fuzzing techniques which
       | will benefit projects across the board.
        
         | 2OEH8eoCRo0 wrote:
         | Nobody at my work has even heard of fuzzing and thought I was
         | making it up. I'm glad senior SWEs are paid so much to keep up
         | with the industry. /s
        
         | sneak wrote:
         | Link to the diff? I always learn better by concrete example
         | than by docs.
        
           | nwsm wrote:
           | The docs have concrete examples if you want-
           | https://go.dev/doc/tutorial/fuzz
        
         | staticassertion wrote:
         | I'm very happy to see fuzzing added to Go, and I don't write Go
         | at all (or every plan to). Bringing concepts like this to the
         | masses is a win for everybody.
        
       | t43562 wrote:
       | I think about Go with pleasure until I remember importing. The
       | miseries I've experienced with modules - the way imports are
       | satisfied......just so hard to understand. Built-in support for
       | SCM sites like github (yuck!). Just struggling to put code in a
       | place where some other bit of my code can use it. The C/C++
       | preprocessor is an abortion and go seems to have made something
       | that solves all the problems I had with that but ends up much
       | worse to use.
        
         | ithkuil wrote:
         | My main misery with modules was due to people renaming their
         | GitHub repositories
        
           | jayd16 wrote:
           | Fork them (just make a copy you own) so you have control?
        
             | ithkuil wrote:
             | Usually my problems are with transitive dependencies. I
             | would have to fork quite a few projects to deal with that.
             | 
             | I wish there was a more systematic way to do "replace",
             | possibly in libraries as well
        
               | thiht wrote:
               | There's a << replace >> directive in go.mod.
        
               | ithkuil wrote:
               | Yeah I know, but it's suboptimal. If you use it your
               | module cannot be "go install" lled, and it doesn't work
               | for libraries
        
               | acchow wrote:
               | Replace in go.mod breaks `go install`?
        
               | ithkuil wrote:
               | Oh yeah, this used to work but some go version ago it
               | stopped working. See
               | https://github.com/golang/go/issues/44840
        
         | [deleted]
        
         | jackielii wrote:
         | Nothing is perfect. I focus on solving problems
        
         | jayd16 wrote:
         | Whats wrong with SCM support?
        
           | turminal wrote:
           | It's not easy to get right and they failed which means it
           | works on some sites but not others (they did make sure all
           | the major hosts work though)
        
         | thiht wrote:
         | Really? That's honestly not an issue I have. My day to day
         | dependency management story is just using go get and go mod
         | tidy. It just works fine, and I work with a fair share of
         | services and dependencies.
         | 
         | Can you share some issues you have?
        
       | didip wrote:
       | Generics!!!
       | 
       | I can't wait for all the different data structure libraries to
       | embrace it. It will make Go adoption in Data Science use-case
       | easier.
        
         | mrtranscendence wrote:
         | I don't see Go ever making headway in data science. For one,
         | it's not fast enough to implement algorithms directly but lacks
         | a decent FFI; it would be burdensome to create the metric ton
         | of new libraries that would have to be put into place. And
         | there are Python libraries for basically everything already,
         | from numeric computing to Bayesian time series to Spark to
         | Torch and TensorFlow.
         | 
         | Plus Go's kind of weird, relative to the languages that many
         | data scientists have experience with.
         | 
         | Maybe I'm being unfair, though.
        
         | leetrout wrote:
         | Some speculation it will allow for better ORMs as well...
        
       | sambeau wrote:
       | LET THE REWRITING BEGIN!...
        
       | mjlee wrote:
       | Release notes are here: https://go.dev/doc/go1.18
        
         | Jolter wrote:
         | This should be the posted link instead of the OP, IMO.
        
       | bborud wrote:
       | I really hope people will show restraint.
        
       | johndfsgdgdfg wrote:
        
         | seanw444 wrote:
         | This has to be satire.
        
         | IceWreck wrote:
         | So switch from one corp to the other ? Thats one extremely
         | biased view.
         | 
         | Use whatever you like, theyre all open source.
        
       | cube2222 wrote:
       | Great to see this!
       | 
       | Generics will drastically improve datastructure libraries.
       | 
       | That said, for people worrying about overcomplication,
       | fortunately methods can't have type parameters. That means
       | ergonomic monads are not possible to implement, and we'll most
       | probably not see the whole functional story play out in Go.
        
         | titzer wrote:
         | > fortunately methods can't have type parameters.
         | 
         | This is quite tricky to implement properly if the compiler
         | doesn't do some form of specialization. (Basically, you need a
         | different vtable entry for each instantiation of a generic
         | method, or you need a runtime lookup to find it). But given
         | that the Go compiler is doing complete specialization, I'm
         | surprised they left this out.
         | 
         | Generic methods (on classes) are the way to emulate first-class
         | polymorphism (roughly, passing around type constructors)
         | without explicit support in the language. It's a limitation
         | that will eventually catch up with you.
        
         | chabad360 wrote:
         | I'm curious why you say fortunately? I find it to be quite a
         | down side that type parameters are missing. In fact it's quite
         | confusing, because there is nothing that indicates a
         | constrained interface can't be used in place of a regular one
         | (until you try it). Personally, I think they should be included
         | simply because they are a side effect of the generics syntax
         | and it's much more confusing without. Also, they increase
         | clarity and type safety, which are two of Go's main advantages.
         | 
         | Also, type parameters were supposed to be included, but were
         | dropped because it made the implementation more complex.
        
         | ed25519FUUU wrote:
         | Plenty of great functional alternatives to Go.
        
           | cube2222 wrote:
           | Definitely! I'd be worried though that functional developers
           | coming to Go (for whatever reason) would try to write Go
           | functionally. That will fortunately be very hard thanks to
           | this limitation.
           | 
           | Nothing specific against functional programming per-se, but
           | as you said, Go's not the language for it.
        
           | zinclozenge wrote:
           | None with the same performance characteristics, ease of use,
           | and ecosystem size. I'm reasonably competent with Rust, but
           | sometimes I don't want to bash my head against the borrow
           | checker or litter my code with copy/clone. Go hits a nice
           | sweet spot, my main quibbles are that there's no native
           | iterators/comprehensions or sum types with compiler checked
           | exhaustive matching. With generics we can get libraries that
           | allow for more functional style programming, and golangci-
           | lint has a linter for exhaustiveness.
        
             | cardanome wrote:
             | Ocaml.
             | 
             | Insanely fast compiler. Great type system. Functional
             | programming at its best but still relatively pragmatic and
             | easy to mix in some imperative code if need be.
             | 
             | It is a bit more complicated than Go and the ecosystem is
             | maybe a bit more patchy but other than you will have a good
             | time.
        
             | SureshG wrote:
             | > None with the same performance characteristics,
             | 
             | Most JVM languages (Kotlin/Scala/Clojure) including Java :)
             | In fact kotlin/java has better peak performance than Go.
             | Main advantage for go is the reduced memory footprint.
        
             | kaba0 wrote:
             | Scala is pretty close to Go in terms of popularity and I
             | would argue that it has a _much_ bigger ecosystem due to
             | the JVM. It is also pretty much a typed python in terms of
             | ease of use, and the JVM has stellar performance -- other
             | than small running scripts, for many kind of workloads
             | Java's state of the art GC will have better throughput than
             | Go's.
        
         | acchow wrote:
         | > That means ergonomic monads are not possible to implement
         | 
         | This is a good thing?
        
           | cube2222 wrote:
           | Yes. I'm keeping up with the developments in functional
           | languages, and many of them have lots of ways to do the same
           | thing, with the "recommended" way changing once every 2
           | years.
           | 
           | I intentionally choose Go where idiomatic code 5 years ago is
           | mostly the same as idiomatic code now. Where no matter who
           | writes the code, it ends up being fairly similar. Where I can
           | easily dive into any open source library, understand the code
           | base in 10 minutes, and make the fix I need. Where there's
           | little-to-no bike shedding.
           | 
           | I understand others might have different preferences, but as
           | another comment mentioned, there are a bunch of languages
           | satisfying those preferences very well (which I like very
           | much as well overall, but I don't like using them for serious
           | day-to-day coding). No reason to try to make everybody happy
           | with a single language.
           | 
           | Besides, I also think monads aren't a very good abstraction
           | to use in most of your day-to-day code, so I'm happy I can
           | avoid code using them.
        
       ___________________________________________________________________
       (page generated 2022-03-15 23:00 UTC)