News for hackers. Stuff that matters.
Re:Go 1.18 by philosopher1234 on Tuesday March 15, 2022 @01:38PM (#30688333)
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.

Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @01:57PM (#30688607)
> 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.

Re:Go 1.18 by jrockway on Tuesday March 15, 2022 @02:48PM (#30689334)
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.)

Re:Go 1.18 by cheriot on Tuesday March 15, 2022 @03:04PM (#30689631)
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 })
Re:Go 1.18 by orangecat on Tuesday March 15, 2022 @08:32PM (#30693786)
This is a perfect example of the fundamental and probably irreconcilable disconnect between Go advocates and detractors. To me, your "bad" example is much better: not only is it less code, it directly expresses the intent rather than making the reader infer it from the sequence of manual loops and ifs.
Re:Go 1.18 by akavi on Tuesday March 15, 2022 @02:57PM (#30689478)
Go has multiple return values, so you could instead do:

    matches, mismatches := slices.Partition(xs, func(x) bool { return x == condition });
Re:Go 1.18 by Groxx on Tuesday March 15, 2022 @02:57PM (#30689471)
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.

Re:Go 1.18 by Zababa on Tuesday March 15, 2022 @06:11PM (#30692555)
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.

Re:Go 1.18 by TimothyBJacobs on Tuesday March 15, 2022 @02:56PM (#30689459)
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
Re:Go 1.18 by jchw on Tuesday March 15, 2022 @02:47PM (#30689319)
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.

Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @03:34PM (#30690266)
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.
Re:Go 1.18 by jchw on Tuesday March 15, 2022 @04:32PM (#30691220)
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.
Re:Go 1.18 by throwaway894345 on Wednesday March 16, 2022 @02:45AM (#30695990)
Ah, that makes sense.
Re:Go 1.18 by djbusby on Tuesday March 15, 2022 @02:29PM (#30689044)
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?
Re:Go 1.18 by eacafdcbac on Tuesday March 15, 2022 @02:51PM (#30689372)
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

Re:Go 1.18 by matwood on Tuesday March 15, 2022 @03:13PM (#30689840)
> 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.

Re:Go 1.18 by rob74 on Tuesday March 15, 2022 @02:40PM (#30689208)
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...

Re:Go 1.18 by djbusby on Tuesday March 15, 2022 @03:09PM (#30689752)
Used xdebug profiler, right?
Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @03:22PM (#30690008)
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.

Re:Go 1.18 by eacafdcbac on Tuesday March 15, 2022 @05:17PM (#30691836)
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.
Re:Go 1.18 by kansface on Tuesday March 15, 2022 @02:51PM (#30689374)
> 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!

Re:Go 1.18 by gerbilly on Tuesday March 15, 2022 @02:05PM (#30688723)
> 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 goes¹, 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.

Re:Go 1.18 by philosopher1234 on Tuesday March 15, 2022 @02:24PM (#30688968)
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.

Re:Go 1.18 by ______-_-______ on Tuesday March 15, 2022 @02:30PM (#30689066)
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.
Re:Go 1.18 by philosopher1234 on Tuesday March 15, 2022 @02:42PM (#30689233)
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.

Re:Go 1.18 by tharne on Tuesday March 15, 2022 @03:02PM (#30689585)
> 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.

Re:Go 1.18 by philosopher1234 on Tuesday March 15, 2022 @06:35PM (#30692841)
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.
Re:Go 1.18 by codr7 on Tuesday March 15, 2022 @04:51PM (#30691517)
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.

Re:Go 1.18 by ModernMech on Tuesday March 15, 2022 @02:50PM (#30689368)
> 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.

Re:Go 1.18 by ainar-g on Tuesday March 15, 2022 @02:09PM (#30688785)
> 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.

Re:Go 1.18 by ______-_-______ on Tuesday March 15, 2022 @02:24PM (#30688969)
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.

Re:Go 1.18 by ainar-g on Tuesday March 15, 2022 @02:40PM (#30689209)
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

Re:Go 1.18 by Zababa on Tuesday March 15, 2022 @06:21PM (#30692681)
> 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

Re:Go 1.18 by int_19h on Tuesday March 15, 2022 @10:52PM (#30694789)
Of the top 6 features in this chart, I see only two that are associated with functional languages: the vague "functional language features" catch-all, and ADTs. The rest is commonly found in mainstream imperative languages today.
Re:Go 1.18 by Zababa on Friday March 18, 2022 @01:01PM (#30724667)
My point is that functional languages have all these features, even if some are found in non-functional languages these days. Even functional langauges themselves are often not only functional. You can do OO in Scala, imperative and OO in OCaml. OCaml is actually a good example to talk about, as the recent developments are all about adding multicore, better concurrency and better tooling, something that Go was very good at from the start.

In a way, you can see that the people using these languages that may appear very different are converging to the same "ideal". And that's not a surprise, both languages have a very Unix-y origin, and origin in Pascal/Modula. Go added to that CSP, OCaml added ML. These days OCaml is adding things to better handle the CSP part, and some people are asking for Go to better handle the ML part.

Re:Go 1.18 by thinkharderdev on Tuesday March 15, 2022 @03:34PM (#30690263)
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.
Re:Go 1.18 by tharne on Tuesday March 15, 2022 @02:55PM (#30689440)
> 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.

Re:Go 1.18 by ainar-g on Tuesday March 15, 2022 @03:05PM (#30689652)
> 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...

Re:Go 1.18 by tharne on Tuesday March 15, 2022 @03:16PM (#30689894)
> 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.

Re:Go 1.18 by matwood on Tuesday March 15, 2022 @03:10PM (#30689790)
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.
Re:Go 1.18 by gerbilly on Tuesday March 15, 2022 @02:25PM (#30688987)
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.

Re:Go 1.18 by scns on Tuesday March 15, 2022 @05:44PM (#30692199)
> 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."

Re:Go 1.18 by MAGZine on Tuesday March 15, 2022 @02:38PM (#30689170)
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)?

Re:Go 1.18 by mseepgood on Tuesday March 15, 2022 @02:39PM (#30689192)
> 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.

Re:Go 1.18 by jhgb on Tuesday March 15, 2022 @02:44PM (#30689257)
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.)
Re:Go 1.18 by mseepgood on Tuesday March 15, 2022 @02:48PM (#30689333)
That's a good thing.
Re:Go 1.18 by int_19h on Tuesday March 15, 2022 @10:53PM (#30694800)
It would have been, if they made it as footgun-proof as Wirth's languages generally are.
Re:Go 1.18 by zozbot234 on Tuesday March 15, 2022 @02:12PM (#30688830)
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.
Re:Go 1.18 by kevinmgranger on Tuesday March 15, 2022 @03:05PM (#30689656)
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.

Re:Go 1.18 by kevinmgranger on Tuesday March 15, 2022 @03:14PM (#30689860)
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

Re:Go 1.18 by uryga on Tuesday March 15, 2022 @08:19PM (#30693693)
> But I also don't know any languages where errors _aren't_ values

(look, i know you understand how exceptions work, please bear with me)

yes, Exception objects are technically values, but you don't return them to the caller; you throw them to the, uh, catcher. basically, you get a special, second way of returning something that bypasses the normal one! but in the EaV approach, errors just are returned like every other thing.

the uniformity of EaV comes in handy when doing generic things like mapping a function over a collection - don't have to worry if something will throw, because it's just a value! and that lets you go to some pretty powerful places w.r.t abstraction: see e.g. haskells `traverse`.

but yeah, EaV needs some syntactic sugar to reach ergonomic par with exceptions, otherwise you get if-err-not-nil soup :P

Re:Go 1.18 by kevinmgranger on Tuesday March 15, 2022 @10:45PM (#30694738)
Right, so the concept in Go is misnamed. It's not Errors are Values, it's Errors Have Normal Control Flow.

Returning errors makes many things more manageable, definitely. But where they really shine, like in the mapping example, isn't possible in Go. Unless I'm mistaken with how go generics work.

(By the way, I'm a huge fan of how error handling works in Rust and other related functional languages. Definitely not advocating for the classic way of doing Exceptions).

Re:Go 1.18 by uryga on Wednesday March 16, 2022 @05:09AM (#30696727)
> But where they really shine, like in the mapping example, isn't possible in Go.

oh yeah, definitely! Go's version of EaV with multiple returns is pretty lackluster compared to a proper Result type. afaict it's kind of "the worst of both worlds" -- all of the boilerplate of plumbing errors manually w/ none of the benefits.

Re:Go 1.18 by kevinmgranger on Wednesday March 16, 2022 @11:59AM (#30700444)
Folks are saying that sum types might eventually come to go after some experimenting with generics. It'll be interesting to see where it goes.
Re:Go 1.18 by int_19h on Tuesday March 15, 2022 @10:56PM (#30694826)
Exceptions can still be treated as syntactic sugar for EaV; it just means that every expression has an implicit unwrap-and-propagate.
Re:Go 1.18 by kevinmgranger on Wednesday March 16, 2022 @11:58AM (#30700436)
Definitely. But Go's boilerplate for error handling is an overcorrection from the implicit propogation. As folks have mentioned, Rust's `?` or Swift's `try` strike a nice middle ground.
Re:Go 1.18 by uryga on Wednesday March 16, 2022 @05:16AM (#30696765)
are there any languages that do this? Rust's `?` is similar but the propagation is explicit
Re:Go 1.18 by int_19h on Wednesday March 16, 2022 @06:16AM (#30697063)
That's what I'm saying - any language with exceptions can be treated as if it was all Rust-style Result<T, E>, but with implicit ? after every expression. Well, and E is an open variant (like e.g. extensible variant types in OCaml), unless the language has checked exceptions like Java.
Re:Go 1.18 by keybored on Tuesday March 15, 2022 @02:52PM (#30689387)
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".

Re:Go 1.18 by stouset on Tuesday March 15, 2022 @04:06PM (#30690817)
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.

Re:Go 1.18 by int_19h on Tuesday March 15, 2022 @11:04PM (#30694880)
> Missing features that have no way of being worked around are dismissed off-hand as unnecessary complexity.

You forgot to add the part where, once the features are added after all, they stop being "unnecessary" complexity :)

Re:Go 1.18 by philosopher1234 on Tuesday March 15, 2022 @06:46PM (#30692948)
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?
Re:Go 1.18 by keybored on Friday March 18, 2022 @11:23AM (#30723447)
I was condemning your bad faith argumentation, not the reasons given. Maybe you misunderstood.
Re:Go 1.18 by andrewf on Tuesday March 15, 2022 @01:59PM (#30688641)
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.

Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @02:10PM (#30688795)
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

Re:Go 1.18 by zozbot234 on Tuesday March 15, 2022 @02:33PM (#30689117)
> 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.

Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @02:41PM (#30689231)
> 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).

Re:Go 1.18 by jimbob45 on Tuesday March 15, 2022 @02:29PM (#30689042)
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.

Re:Go 1.18 by AnimalMuppet on Tuesday March 15, 2022 @03:18PM (#30689938)
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.

Re:Go 1.18 by zozbot234 on Tuesday March 15, 2022 @07:36PM (#30693380)
> In fact, Go was designed to enable average programmers to be productive on large systems.

The fallacy in that argument is that effective programming "in the large" requires more features, not less. Sure, there are highly dynamic programming languages that cannot meaningfully support programming beyond the scale of a "personal side project". Ironically for Paul Graham's "Blub" argument, LISP is quite clearly one such language. The same applies to languages such as Python, Ruby or ECMAscript, which would have been among the main alternatives to Go when it was first released.

And one can also fairly argue that Go has in fact made it simpler and easier to "program in the large" compared to C++, Java or C#, which were the other major alternatives to Go around that same time. So Pike's argument is not wrong as far as it goes. It is merely of limited applicability, because the jury is very much still out wrt. more recent and arguably higher-level languages like ReasonML, Kotlin, Dart, Erlang and yes, Rust. It's silly to conflate these languages with the likes of Python or C++, that is indeed the kind of argument that "Blub" was written for!

Re:Go 1.18 by phplovesong on Wednesday March 16, 2022 @01:54AM (#30695767)
Disclaimer: I don't use Go professionally

When compared to say, Ocaml Go definitely lacks some of the niceties of a type system (even now with generics). With ocaml i use recursion in almost every case i need to reduce / map something. Pattern matching + type constructors are VERY powerful and produces very safe code.

That said, i really like Go as a language. It lacks many higher level abstractions, and the coding style is very procedural. It's boring, and stops you from being to clever. Simply put, i get shit DONE in Go without much thinking. sometimes i work for hours in Ocaml to get a semi "easy" function to work correctly. With Go it's just write and things usually work.

Go has very good concurrency primitives for 95% of use cases. Ad hoc concurrency in Ocaml is still a pain (the new effect system WILL make this better) as you need to pick and choose between Ltw or async and then pray libraries support the one you chose.

For me Ocaml is still a language (that i love) for "being smart about it". And good ocaml code is truly beautiful and safe. Go on the other hand is about getting shit done. I can be productive in Go and then refactor later.

I really like that Go has such a good core that comes with the essentials, so you rarely need higher level dependencies (i would not write a databada driver myself).

Go sits in a spot that's well designed and has the right tools and brings good enough safety to the average app.

Re:Go 1.18 by FpUser on Tuesday March 15, 2022 @02:15PM (#30688873)
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.
Re:Go 1.18 by scottjg on Tuesday March 15, 2022 @02:23PM (#30688960)
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

Re:Go 1.18 by FpUser on Tuesday March 15, 2022 @02:28PM (#30689036)
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.
Re:Go 1.18 by bcrosby95 on Tuesday March 15, 2022 @02:40PM (#30689214)
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.

Re:Go 1.18 by nicoburns on Tuesday March 15, 2022 @02:11PM (#30688807)
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.
Re:Go 1.18 by Thaxll on Tuesday March 15, 2022 @02:17PM (#30688890)
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 ...

Re:Go 1.18 by nicoburns on Tuesday March 15, 2022 @02:28PM (#30689040)
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.

Re:Go 1.18 by philosopher1234 on Tuesday March 15, 2022 @02:53PM (#30689402)
Perhaps the trouble is when you encounter other peoples abstractions, or when you return to abstractions you’ve long since discarded :)
Re:Go 1.18 by nicoburns on Tuesday March 15, 2022 @03:01PM (#30689551)
The key abstractions that I want access to are standard ones like "map", "filter", "reduce", and data structures like "Option", "Result", "Future, "ConcurrentHashMap".
Re:Go 1.18 by kaba0 on Tuesday March 15, 2022 @03:43PM (#30690425)
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.

Re:Go 1.18 by jhgb on Tuesday March 15, 2022 @07:53PM (#30693509)
I suspect that this is like arguing that if the Latin alphabet is more practical than the Chinese script, we should just jump straight to binary symbols. The fact that binary symbols would make writing impractical again doesn't negate the fact that the Latin alphabet is more practical than the Chinese script.
Re:Go 1.18 by didibus on Tuesday March 15, 2022 @02:33PM (#30689120)
> 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.

Re:Go 1.18 by jhgb on Tuesday March 15, 2022 @02:41PM (#30689216)
> 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.

Re:Go 1.18 by kaba0 on Tuesday March 15, 2022 @02:59PM (#30689516)
> 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.

Re:Go 1.18 by didibus on Tuesday March 15, 2022 @10:37PM (#30694686)
Cross-compilation is a big deal I'd say, I wouldn't brush it off as insignificant.

Even if I ignore cross-compilation, what other language has easy and fast native compilation, that produces relatively performant and low memory programs, is properly garbage collected, and has a good library ecosystem as well as a good concurrency story?

Re:Go 1.18 by andyfleming on Tuesday March 15, 2022 @02:41PM (#30689228)
This is spot on, for me. The compiler and runtime are attractive, but the missing language niceties are an annoyance.
Re:Go 1.18 by rob74 on Tuesday March 15, 2022 @02:49PM (#30689345)
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.
Re:Go 1.18 by erik_seaberg on Tuesday March 15, 2022 @05:21PM (#30691888)
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.

Re:Go 1.18 by robocat on Tuesday March 15, 2022 @07:52PM (#30693508)
The syntactic choice of using square brackets instead of angle brackets for generics appears to be due to optimising for parsing. User clarity is decreased to allow for code optimisation IMHO.

From https://groups.google.com/g/golang-nuts/c/7t-Q2vt60J8 the following:

  Angle brackets require unbounded parser look-ahead or type information in certain situations (see the end of this e-mail for an example). This leaves us with parentheses and square brackets. Unadorned square brackets cause ambiguities in type declarations of arrays and slices, and to a lesser extent when parsing index expressions. Thus, early on in the design, we settled on parentheses as they seemed to provide a Go-like feel and appeared to have the fewest problems.

  As it turned out, to make parentheses work well and for backward-compatibility, we had to introduce the type keyword in type parameter lists. Eventually, we found additional parsing ambiguities in parameter lists, composite literals, and embedded types which required more parentheses to resolve them. Still, we decided to proceed with parentheses in order to focus on the bigger design issues.
Also https://archive.ph/tZJbB archive of original proposal https://go.googlesource.com/proposal/+/refs/heads/master/des... which suggested using normal parentheses (!) for reasons:

  Why not use the syntax F<T> like C++ and Java?

  When parsing code within a function, such as v := F<T>, at the point of seeing the < it's ambiguous whether we are seeing a type instantiation or an expression using the < operator. Resolving that requires effectively unbounded lookahead. In general we strive to keep the Go parser efficient.

  Why not use the syntax F[T]?

  When parsing a type declaration type A [T] int it's ambiguous whether this is a generic type defined (uselessly) as int or whether it is an array type with T elements. However, this could be addressed by requiring type A [type T] int for a generic type
Aside: it isn’t clear why not just make white space before the angle bracket significant - their examples of parsing problems are only if the code is not formatted “correctly” using gofmt. I think making the user type a space before greater-than would fix the parsing problem, and that seems like a reasonable compromise to reduce confusion for go vs most other languages. Square brackets usually mean indexing or arrays, and go breaks that pattern flummoxedly.

  F<T> versus f < t >
are syntactically different to read anyway ( whitespace is significant to pro grammers and writers for syntax ,for example).
Re:Go 1.18 by int_19h on Tuesday March 15, 2022 @11:01PM (#30694854)
How does using [] for generics decrease user clarity? They're both just grouping characters. If the argument is that [] is easy to confuse with indexing, then by the same token <> is also easy to confuse with comparison operators.

One could also argue that [] is the better choice precisely because it is similar to indexing a map - a generic type can be seen as a map of types to other types.

Re:Go 1.18 by srer on Wednesday March 16, 2022 @03:56AM (#30696341)
It certainly does for me. It ties into this quote:

> Why not use the syntax F<T> like C++ and Java?

A great number of us are used to seeing <> rather than [] for generics.

It would seem limitations in Go's parser outrank a popular norm.

Re:Go 1.18 by int_19h on Wednesday March 16, 2022 @06:13AM (#30697051)
If you look at some of the contortions that e.g. C# has to go through when evolving the language, due to numerous ambiguities between <> used for types and <> used in expressions, I think it's still a very sensible choice.
Re:Go 1.18 by robocat on Wednesday March 16, 2022 @09:03PM (#30706259)
Square brackets in go have their own parsing issues (see my original comment). I haven’t found much discussion on how any parsing issues were resolved (presumably any issues needed resolution for backwards compatibility?).

As an outsider it appears to me that the choice for square brackets has been made mostly for stylistic non-technical reasons, but perhaps politically that would be difficult to rationalise to the user-base! Making whitespace significant before comparison/shift operators (matching the gofmt layout) surely solves the stated practical issue of lookahead parsing; although I admit many language geeks would say significant space characters were an ugly solution.

To agree with you: there is a really good discussion on the downsides of <> here —https://lobste.rs/s/fmcviy/language_designers_stop_using_for — certainly square brackets are used for generics in other languages (Scala, Python, Nim, Eiffel).

Regardless, the point is moot, given that the syntax is now concrete!

> then by the same token <> is also easy to confuse with comparison operators

Not really, given that comparison/shift operators are not used in types, whereas [] is used in types. Perhaps go-lang wanted to reserve angle brackets for constraint operators a la Scala <: et al. </wink>.

Disclaimer: I have little experience with generics or language design. I am just very curious if there is a divergence between the stated reasons for the design, versus any unstated reasons.

Re:Go 1.18 by marwatk on Tuesday March 15, 2022 @02:56PM (#30689451)
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.

Re:Go 1.18 by twsted on Tuesday March 15, 2022 @04:24PM (#30691092)
If I rethink about how long I was kept away from go by its error handling and then I fell in love with it...
Re:Go 1.18 by matthewmacleod on Tuesday March 15, 2022 @03:02PM (#30689597)
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.

Re:Go 1.18 by stouset on Wednesday March 16, 2022 @12:17AM (#30695265)
This is my critique of go too. It's really easy to write code that works well for all of the cases I can think to test. But it is strictly impossible to write code where I can make guarantees of robustness.

These little warts that prevent that are everywhere: lack of sum types (no Option / Result), half-assed enums, no real ability to make things const, inability to express exhaustive switch statements, having to downcast to `interface{}/any`, nil, typed nil, and on and on and on.

The longer I develop software, the less I care about being able to write software that works and the more I care about being able to write software that doesn't fail. The former is table stakes, and I can throw together something that works in virtually any language. The latter is what not only prevents me from spending nights and weekends fixing problems, but also allows me to finish software and truly move on to new projects without having to constantly play whack-a-mole fixing new issues that keep coming up.

Re:Go 1.18 by oconnor663 on Tuesday March 15, 2022 @02:57PM (#30689466)
> 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.

Re:Go 1.18 by kaba0 on Tuesday March 15, 2022 @03:44PM (#30690444)
And the stupidest of all: defer is function-scoped, not block.
Re:Go 1.18 by oconnor663 on Tuesday March 15, 2022 @04:14PM (#30690916)
I don't like calling any of these things stupid. They're tradeoffs, and I can respect why they were made.
Re:Go 1.18 by kaba0 on Tuesday March 15, 2022 @06:01PM (#30692427)
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

Re:Go 1.18 by kevinmgranger on Tuesday March 15, 2022 @10:50PM (#30694771)
It enables one to conditionally set up cleanup within the function. If it was block scoped, you couldn't do something like `if shouldDoSideEffect { defer something() }`

If it was scope-based, there would be just as many people complaining that it isn't function based.

Re:Go 1.18 by kaba0 on Wednesday March 16, 2022 @04:00AM (#30696365)
You could just do `defer if shouldDoSideEffect { something() }`
Re:Go 1.18 by kevinmgranger on Wednesday March 16, 2022 @11:56AM (#30700411)
That's slightly different, though. The first is "when this is true, earlier in the function, queue up running something at the end of the function." This is "at the end of the function, if this is true, do something."

They _should_ be identical, unless shouldDoSideEffect changes.

Yes, mutability is bad. One shouldn't change that. But avoiding "you're holding it wrong" footguns was the original goal, right?

Don't get me wrong, having both would be nice. Maybe something like `after` for function scope and `defer` for block scope. But that starts to erode the "simplicity" of Go, I guess.

Re:Go 1.18 by oconnor663 on Wednesday March 16, 2022 @12:07PM (#30700575)
I think that gets unwieldy in more complicated cases. You might want to write:

    if condition_A {
        acquire_A()
        defer release_A()
    } else if condition_B() {
        acquire_B()
        defer release_B()
    } else {
        acquire_C()
        defer release_C()
    }
But with block-scoped defer you'd have to write something like:

    if condition_A {
        acquire_A()
    } else if condition_B {
        acquire_B()
    } else {
        acquire_C()
    }
    defer func() {
        if condition_A {
            release_A()
        } else if condition_B {
            release_B()
        } else {
            release_C()
        }
    }()
Maybe the syntax here could be better with some kind of defer-if added to the language, but it's the non-locality of the cleanup that's the real downside. The whole point of the defer keyword is to let you put cleanup right next to resource acquisition, to make code easier to audit and maintain, and we lose that here. (Also this version might not even be correct, if the conditions change their values over time.)

To be honest, I think Rust's combination of destructors and move semantics is really the ideal way of doing cleanup, with C++ coming pretty close too. But given a defer keyword, I can see situations where having it block-scoped would be painful.

Re:Go 1.18 by mcronce on Tuesday March 15, 2022 @02:10PM (#30688800)
> 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.

Re:Go 1.18 by jatone on Wednesday March 16, 2022 @01:39PM (#30701727)
> Error handling is a big one for me. This could be generalized to lack of expressivity;

this has been shown over and over to be incorrect. go programs are within the ballpark of other languages in terms of LOC. usually the examples given are niche use cases that impact an extremely small amount of code.

golang is looking for ways to make it more ergonomic just hasnt found a decent path forward yet. interestingly your sum types complaint might allow for it eventually.

> Go really likes forcing you to either write a ton of tests or discover your errors in production

this is just not true compared to most languages. evidence please. given the prevalence of dynamic languages in the wild today its most likely the opposite. i know my golang tests tend to be less in number than java or any dynamic language.

>Farther down the list is escape analysis. Rather than just giving me control over whether allocation happens inline or indirect

also not true, golang absolutely gives you the ability to control this. but its guarded by rules. rules that prevent you from screwing up and causing memory issues. this is a good thing.

Re:Go 1.18 by ainar-g on Tuesday March 15, 2022 @01:53PM (#30688544)
> 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.
Re:Go 1.18 by earthboundkid on Tuesday March 15, 2022 @02:00PM (#30688650)
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.
Re:Go 1.18 by freedomben on Tuesday March 15, 2022 @02:07PM (#30688756)
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.

Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @02:16PM (#30688879)
> 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.

Re:Go 1.18 by freedomben on Tuesday March 15, 2022 @02:37PM (#30689162)
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.

Re:Go 1.18 by rat9988 on Tuesday March 15, 2022 @02:13PM (#30688840)
> 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.

Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @02:19PM (#30688918)
> 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.

Re:Go 1.18 by rat9988 on Tuesday March 15, 2022 @02:33PM (#30689109)
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.
Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @03:00PM (#30689543)
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).
Re:Go 1.18 by kaba0 on Tuesday March 15, 2022 @03:48PM (#30690498)
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.
Re:Go 1.18 by goodoldneon on Tuesday March 15, 2022 @02:52PM (#30689382)
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).
Re:Go 1.18 by apazzolini on Tuesday March 15, 2022 @02:01PM (#30688667)
Here's a blog series that you'll likely find enlightening: https://jesseduffield.com/Gos-Shortcomings-1/
Re:Go 1.18 by philosopher1234 on Tuesday March 15, 2022 @02:27PM (#30689006)
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.
Re:Go 1.18 by candiddevmike on Tuesday March 15, 2022 @02:16PM (#30688883)
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.

Re:Go 1.18 by didibus on Tuesday March 15, 2022 @02:58PM (#30689496)
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.

Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @02:25PM (#30688978)
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.
Re:Go 1.18 by vlunkr on Tuesday March 15, 2022 @02:39PM (#30689195)
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.
Re:Go 1.18 by quaunaut on Tuesday March 15, 2022 @02:23PM (#30688959)
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.

Re:Go 1.18 by scns on Tuesday March 15, 2022 @07:08PM (#30693145)
> Algebraic data types were introduced in Hope, a small functional programming language developed in the 1970s at the University of Edinburgh. [0]

It predates Miranda and Haskell and is contemporaneous with ML, also developed at the University. [1]

ML had them too [2]

[0] https://en.wikipedia.org/wiki/Algebraic_data_type#Programmin...

[1] https://en.wikipedia.org/wiki/Hope_(programming_language)

[2] https://en.wikipedia.org/wiki/ML_(programming_language)

edit: add ML

Re:Go 1.18 by Zababa on Tuesday March 15, 2022 @02:05PM (#30688738)
> 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.

Re:Go 1.18 by s3graham on Tuesday March 15, 2022 @02:26PM (#30688997)
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.
Re:Go 1.18 by tacotacotaco on Tuesday March 15, 2022 @02:07PM (#30688764)
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.

Re:Go 1.18 by synergy20 on Tuesday March 15, 2022 @02:34PM (#30689132)
'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.

Re:Go 1.18 by bcrosby95 on Tuesday March 15, 2022 @01:58PM (#30688610)
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.

Re:Go 1.18 by stouset on Tuesday March 15, 2022 @03:38PM (#30690334)
> 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.

Re:Go 1.18 by morelisp on Wednesday March 16, 2022 @02:35PM (#30702352)
None of your proposals truncate a Unicode string to the first 63 characters. Go and Rust are at least honest about this. Ruby lies about what you're indexing and makes you pay O(n) to do it. (And no, that's not the way you're "supposed to" truncate to a codepoint offset in Go, but it's also true that there's no function to do it in the standard library - in part because that's rarely what you really want to do and it would get abused to do such.)

> When you're handed a string you can generally assume it's been parsed and validated under that character set

But it might not have been. It's a weakass guarantee, the same Go gives you, except in Go it's UTF-8-or-garbage, vs. Ruby's could-be-anything-and-could-still-be-garbage.

Re:Go 1.18 by int_19h on Tuesday March 15, 2022 @11:10PM (#30694917)
> this simplicity just kicks the cans of complexity and verbosity downstream onto its users

I still think that append() is the arch-example of that. I can't think of another high-level PL that doesn't have an atomic add-item-to-collection operation (either in the language or in stdlib) without requiring the user to coordinate all the moving parts.

Re:Go 1.18 by beltsazar on Tuesday March 15, 2022 @02:44PM (#30689255)
> 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.

Re:Go 1.18 by int_19h on Tuesday March 15, 2022 @10:42PM (#30694710)
I doubt that sum types are going to be a big target, given the lack of support for them in many other mainstream languages. The lack of generics was standing out so much precisely because Go was the only mainstream statically typed PL without them by choice.
Re:Go 1.18 by zemo on Tuesday March 15, 2022 @05:17PM (#30691842)
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.

Re:Go 1.18 by ParetoOptimal on Friday March 18, 2022 @08:43AM (#30721439)
> 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?

Because swaths of code written in a language where it's easier to make mistakes affects all parties and entrenches said language.

Imagine a book on programming an unreadable language like Befunge was given out to low income schools across the world, those people ended up organizing, and by sheer number and force cranked out software the industry depended upon.

Is it unethical to see the downside, point it out, but appreciate what was accomplished?

I think about the dilemma of socioeconomics preventing language choice from being a consideration and language mattering for writing better software a lot though.

Re:Go 1.18 by ParetoOptimal on Friday March 18, 2022 @08:34AM (#30721363)
> 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.

This is easy.

Go programmers are more likely to claim language choice doesn't impact software much.

Haskell programmers are more likely to claim language choice does matter a large amount.

That means there's not as much reason for Go programmers to criticize other languages because they don't see it as mattering much.

I think "language doesn't matter" is a hypocritical position that people make in bad faith though.

That said, Go programmers definitely criticize other languages including Haskell for not being inferior to Go's brand of "simplicity".

Re:Go 1.18 by philosopher1234 on Tuesday March 15, 2022 @06:52PM (#30693005)
I love this take, its very interesting! Thanks for sharing.
Re:Go 1.18 by icholy on Tuesday March 15, 2022 @01:48PM (#30688484)
People are upset that their favourite language didn't get as popular as Go.
Re:Go 1.18 by echelon on Tuesday March 15, 2022 @01:51PM (#30688512)
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.

Re:Go 1.18 by icholy on Tuesday March 15, 2022 @01:56PM (#30688590)
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.
Re:Go 1.18 by lolinder on Tuesday March 15, 2022 @02:22PM (#30688949)
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...

Re:Go 1.18 by icholy on Tuesday March 15, 2022 @09:55PM (#30694367)
Why are you saying "only"? Are we looking at the same list?
Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @02:28PM (#30689038)
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.
Re:Go 1.18 by mcronce on Tuesday March 15, 2022 @02:14PM (#30688861)
While true, that doesn't really change the situation for the individuals who require <missing feature>
Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @02:31PM (#30689082)
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.
Re:Go 1.18 by lolinder on Tuesday March 15, 2022 @03:31PM (#30690219)
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.

Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @03:44PM (#30690443)
> 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").

Re:Go 1.18 by mcronce on Tuesday March 15, 2022 @05:31PM (#30692027)
> 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.

Re:Go 1.18 by philosopher1234 on Tuesday March 15, 2022 @06:55PM (#30693028)
>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.

Re:Go 1.18 by mcronce on Tuesday March 15, 2022 @08:07PM (#30693606)
In the context of a discussion about programming languages, no, it really doesn't. Not all slopes are slippery.
Re:Go 1.18 by philosopher1234 on Tuesday March 15, 2022 @08:24PM (#30693726)
It seems like it does to me. Why doesn't it?
Re:Go 1.18 by mcronce on Tuesday March 15, 2022 @08:47PM (#30693905)
Because not all statements apply to all situations.
Re:Go 1.18 by philosopher1234 on Tuesday March 15, 2022 @10:14PM (#30694497)
This is really vague and unhelpful. I’m going to interpret this to mean you’re not interested in actually explaining the problem, sorry if I’m mistaken.
Re:Go 1.18 by mcronce on Wednesday March 16, 2022 @10:02AM (#30698947)
There's not really any further way to "actually explain" that, often, when a person says something, context matters and it isn't universally applicable.

I'm not even sure why I'm having to explain this. It's is a pretty obvious thing.

Re:Go 1.18 by philosopher1234 on Wednesday March 16, 2022 @12:45PM (#30701096)
Obviously its not obvious to me. I've had enough of your games, if you're interested in an actual productive conversation, feel free to reply, otherwise I want nothing to do with you.
Re:Go 1.18 by throwaway894345 on Wednesday March 16, 2022 @02:43AM (#30695982)
For what it’s worth, this is the read I’ve gotten from this thread as well. I’m not sure how else to interpret the parent’s remarks—his responses seem evasive rather than clarifying.
Re:Go 1.18 by philosopher1234 on Wednesday March 16, 2022 @03:43AM (#30696276)
Yea I noticed that in your interactions with them too. Also while I’m here I want to compliment you on your articulations of the strengths of go throughout this comments section! They’ve been very well put/compelling and helped me understand better how to express the things I like about go in the face of its detractors, which is a constant struggle for me.
Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @06:52PM (#30693003)
> 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.

Re:Go 1.18 by mcronce on Tuesday March 15, 2022 @08:09PM (#30693631)
> there’s pretty wide consensus even among Go detractors about these qualities

[citation needed]

> there are plenty of people willing to think differently and reap the benefits

"Reap the benefits" is, again, subjective. It's something you like, not something objectively beneficial or worth the trade-offs in all, most, or even necessarily many projects.

This is precisely the unduly arrogant attitude amongst Gophers that others have already mentioned several times in this thread.

Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @08:41PM (#30693856)
You’re welcome to disbelieve me on the consensus. I’m not trying to persuade you of anything.

> "Reap the benefits" is, again, subjective. It's something you like, not something objectively beneficial or worth the trade-offs in all, most, or even necessarily many projects.

Of course, productivity isn’t for everyone. Sometimes for personal projects I’ll opt for things that exercise my creativity and cleverness over the purely productive or pragmatic.

> This is precisely the unduly arrogant attitude amongst Gophers that others have already mentioned several times in this thread.

Hah! This made me laugh. Yes, I disagree with you therefore I must be arrogant. (:

Re:Go 1.18 by mcronce on Tuesday March 15, 2022 @08:49PM (#30693918)
lol...you even take criticism arrogantly. Impressive. It wasn't a personal attack, it was a statement of fact, but thanks for making my point even more clearly for me - not only in your response to that, but in your assertion that your opinion based on your experience is fact. Appreciated.

Restated: You aren't arrogant because you disagree with me. You're arrogant because the things you say and the way you say them are arrogant.

Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @10:10PM (#30694469)
Look, I’m not interested in a slapfight. Enjoy your evening.
Re:Go 1.18 by mcronce on Tuesday March 15, 2022 @03:11PM (#30689800)
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).

Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @03:31PM (#30690223)
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++.

Re:Go 1.18 by mcronce on Tuesday March 15, 2022 @05:19PM (#30691867)
> 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`?

Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @08:55PM (#30693970)
> Performance only drives one of the two alternatives.

Right, so use dynamic dispatch by default.

> Seriously, how many dependency management paradigms have we gone through so far, and the best thing we can come up with is `go mod`?

Agreed that the road to go mod has been tumultuous, but go mod is in the top tier of dependency managers, which is perhaps a sad indictment of dependency managers. Most languages still don’t offer reproducible builds, and several mainstream languages require that you generate your list of dependencies in an imperative DSL—or at least these build systems are the most popular, which brings us to another problem: some languages don’t even have a single standard tool! From dependency managers, let’s look at build tools: how many build completely static binaries by default? How many make you script the build in an imperative DSL? How many punt altogether? How many languages compile to native code in seconds or faster? How many languages can trivially cross-compile virtually any package? How many languages still make you spin up a CI job to build and publish source code packages? How many make you spin up a CI job to build and publish documentation packages? How many support testing out of the box? Benchmarking? Fuzzing? Formatting? Profiling?

As far as I can tell, Go trounces virtually every other language on tooling (Rust seems to do pretty well). One area where ago doesn’t do as well is debugging—I know Go has delve, but I understand it to be limited (haven’t tried it in a long time though to be honest).

Re:Go 1.18 by int_19h on Tuesday March 15, 2022 @11:15PM (#30694954)
You can dig a hole of any size with a shovel, given enough time. But I wouldn't fault people who refuse to dig a large hole with a shovel after they've seen an excavator at work.
Re:Go 1.18 by throwaway894345 on Wednesday March 16, 2022 @02:40AM (#30695969)
This analogy just reduces down to “I think generics are more fit-for-purpose” which is just another way of saying “I think generics are better”. And I certainly think there’s a fair amount of merit to generics, but the folks who have seriously programmed with and without generics are much less fervent supporters of generics (if they support them at all) than the generics-advocates who have only used languages that make heavy use of them. I won’t try to analogous this to power tools or cars or anything else because such analogies are never enlightening and usually at least a little corny.
Re:Go 1.18 by echelon on Tuesday March 15, 2022 @01:56PM (#30688595)
Well, I can only speak for myself :)
Re:Go 1.18 by pjmlp on Tuesday March 15, 2022 @02:04PM (#30688713)
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.