News for hackers. Stuff that matters.
Re:Go 1.18 by pie_flavor on Tuesday March 15, 2022 @06:43PM (#30692922)
I wish I understood how people can say 'this will result in so much more weird boilerplate garbage code' as it solves a problem that has resulted in an absolutely ludicrous amount of weird boilerplate garbage code. You're not trading off generic code vs non-generic code. Problems are generic. For solving generic problems, you're trading off the generic code that best expresses them, for codegen, dynamic downcasting, or Ctrl-V. The first two are not simpler (in the Go way) than generics, and the third is an antipattern in every programming environment.
Re:Go 1.18 by yashap on Wednesday March 16, 2022 @12:18AM (#30695274)
I’m a big fan of Go adding generics, but I can see some of what people are worried about. I don’t think it’s “business logic that would benefit from being made generic”, it’s that generics allow people to write new data structures that aren’t currently reasonable to write in Go. For example:

- Sets

- Trees/graphs

- Stacks/queues

- List-like data structures with different performance characteristics than slices

- Monadic data structures you find in functional languages, like Option (for dealing with the lack of a value), Either (one of two possible values), Future (basically either a success or an error, computed asynchronously), etc.

I’m sure we’ll see popular libraries providing all of the above, and more. Generics will make for a wider variety of programming styles in Go, which has downsides as well as upsides.

Go will likely get a bit more functional/declarative/high-level, a bit less imperative/procedural/low-level. It’s not about to become Haskell or Scala, but maybe a bit more like TypeScript or statically typed Python, a bit less like C.

Re:Go 1.18 by bobbylarrybobby on Wednesday March 16, 2022 @01:12AM (#30695545)
Why would anyone be worried about being able to write code that more closely matches the problem domain?
Re:Go 1.18 by rob74 on Wednesday March 16, 2022 @01:43AM (#30695715)
Spending lots of effort designing your type system to match your problem domain (or rather, what you think is your problem domain) is a pitfall which was made less likely by "classic" Go because the available types were very straightforward. Which also made it easier to refactor your code when you inevitably realized your initial approach didn't match the problem domain that well after all (or the problem domain changed, as it tends to do when you maintain an application over several years). And I totally understand that people are worried having generics will change this.
Re:Go 1.18 by jeltz on Wednesday March 16, 2022 @06:03AM (#30696997)
Because generics rarely help with that. I love generics for writing libraries and for giving me libraries which are easy to use but my business logic is almost never generic. Most problem domains I have worked in have not been very generic.
Re:Go 1.18 by baby on Wednesday March 16, 2022 @04:56AM (#30696646)
Readability, complexity, security
Re:Go 1.18 by manigandham on Wednesday March 16, 2022 @01:26AM (#30695615)
Why are new data structures worrying?
Re:Go 1.18 by yashap on Wednesday March 16, 2022 @01:55AM (#30695772)
The downside is they’ll make Go code less uniform. Do you represent nullability with a nil-able pointer, or an option monad? To transform a list, do you loop over a slice, or map/flatMap/filter over a more functional data structure? etc.

Pre-generics, Go has been a very limited language. On the downside it’s verbose and error-prone, on the upside it’s very uniform. I think generics will make it less verbose and error-prone, but also less uniform - stylistic differences from programmer to programmer will be greater, similar to other high level languages.

Re:Go 1.18 by zozbot234 on Wednesday March 16, 2022 @03:49AM (#30696315)
> Pre-generics, Go has been a very limited language. On the downside it’s verbose and error-prone, on the upside it’s very uniform.

Except that this kind of uniformity inherently tends to disappear in larger projects, to be replaced by increased complexity. Java was also designed to be a "simple" language, one trivially understandable by hordes of low-skilled code monkeys, and yet look at the added layers of complexity in many Java enterprise frameworks. More full-featured languages, when properly designed (especially, avoiding the feeping creaturitis of something like Scala), make it easier not harder to manage inherent complexity at a larger and larger scale of development. But Go is now basically stuck with its constrained feature set, and Go developers cannot easily avail themselves of these tools. This is why so many devs criticize this particular design goal; it's pretty much incoherent.

Re:Go 1.18 by baby on Wednesday March 16, 2022 @04:59AM (#30696666)
I’ve audited a bunch of complex codebases in Golang that were very readable. Surprisingly readable actually
Re:Go 1.18 by dividedbyzero on Wednesday March 16, 2022 @05:58AM (#30696976)
In my experience, that happens when people consciously manage the way they use their language, or have the trained instinct to do so unconsciously. At a certain scale choice of language doesn't really influence this all that much (as long as the language isn't Perl I guess, I've never seen that done cleanly.)

I've worked on really neat big Scala codebases and really terrible big Go codebases – a determined developer can make a mess regardless of language, and for some cases it's actually easier to end up in that place with Go than with a more expressive language with a more comprehensive stdlib. Go isn't well-equipped for a number of things, and if you have to do those a lot, generated code and workarounds like the pseudo-sets people build from maps really become liabilities.

From what I've seen as far as complex codebases are concerned, I'd say Go can be very readable for small-ish programs that lend themselves well to Go's opinionated standard library and way of doing things, but I'd definitely want to use something more expressive at scale or for anything that doesn't fit into Go's limitations well.

Re:Go 1.18 by baby on Thursday March 17, 2022 @12:53AM (#30707793)
I couldn't disagree more. Everything I've read in Java was a huge messy pile of spaghetti code. C++ and C can definitely become unreadable very quickly. Rust, on the other hand, I find harder to mess, although there are still lots of ways to do it. And then there's Golang, I've read so much Golang code that I'm surprised when I run into something that isn't readable. Happened to me once, obviously the code had been written by Java developers (factories lol)
Re:Go 1.18 by ezst on Wednesday March 16, 2022 @06:50AM (#30697270)
> when properly designed (especially, avoiding the feeping creaturitis of something like Scala)

What I find interesting here is that Scala has the reputation of being a complex language, while its syntax and grammar are among the simplest and most straightforward there is: https://images.app.goo.gl/K1NTGUP4G9T6wfY48

I believe that this is what "scalable" means in the eyes of its creator: it offers very powerful abstractions to be adequate for mundane tasks (e.g. file-level scripting) up to complex systems and problem spaces.

Yes, as a consequence, people have created libraries and codebases with Scala that are inadequately complex and abstract for the problem at hand, but that's not something one should blame on the language but on the project/company culture. Same is true for any language: C++ templates can be abused in ludicrous ways, some of Java's design patterns make you wish inheritance would be forbidden, python's module imports potentially overwriting globals and other footguns.

No language can be dumbed-down so much that the resulting codebase becomes immune to some amount of "abstraction management", not go, not even python. Once this is understood and accepted, it becomes obvious that it's not worthy to castrate a language on the basis of "simplicity", because eventually this complexity will be warranted at a point in the future or for some aspect of the project.

I think the go designers did the right thing here, I don't think this will bring dramatic changes in how the language is used, and will actually help with "managing abstraction" where it's due.

Here's more on that: https://www.lihaoyi.com/post/StrategicScalaStylePrincipleofL...

Re:Go 1.18 by lifty on Wednesday March 16, 2022 @06:03AM (#30696995)
Java code got complex after adding generics, not before. In a big Go codebase, even if it’s complex, the styling and patterns are the same, so it’s easier to follow. That might change to some degree with the addition of generics.
Re:Go 1.18 by ezst on Wednesday March 16, 2022 @07:01AM (#30697351)
That's not true. Java was notorious for AbstractFactoryProducerArtifactFactory and awful inheritance-based patterns long before that.

You can't dumb down a language and expect the complexity of the problem space to go away (developers will have to cope with it one way or another), and you can't expect the programming language alone to be the sole judge of what's an acceptable level of abstraction (or architects would have been made redundant by now).

Re:Go 1.18 by baby on Wednesday March 16, 2022 @04:58AM (#30696654)
Wish I could upvote this comment more. This is the best summarized take on the introduction of generic in Go. It’s exciting, but frightening at the same time. Will this destroy the simplicity and the readability of Golang?
Re:Go 1.18 by rob74 on Wednesday March 16, 2022 @01:46AM (#30695725)
Because they add cognitive load, make it harder to read a piece of code and understand what it is doing (and therefore can hide errors) etc. etc.
Re:Go 1.18 by torginus on Wednesday March 16, 2022 @06:04AM (#30697001)
I'm kind of not sure what's necessary that wasn't there before. Go has:

- List

- Array

- Dictionary

- Set (map with empty value)

- Stack (easily emulated with list)

- Queue (channel)

Other than the ones mentioned before, the only ones I've ever used were a priority queue and sorted map (AVL-tree), and even those were rare. Other than these I used others that were so application-specific, that it made no sense to be generic. Based on this there's no strong case for why generics have to be in the language. Not hating, but I'm not convinced either way.

Re:Go 1.18 by _wldu on Wednesday March 16, 2022 @01:37AM (#30695681)
Go has maps already. A set is just a map where the key and value are the same thing.
Re:Go 1.18 by yashap on Wednesday March 16, 2022 @01:47AM (#30695735)
Sets tend to have methods like difference, union and intersection - with a map[T]bool, if you want to find the difference, union or intersection of 2 sets, you have to do all of that with much more verbose (and error prone) loops. Also, the type being a set carries a semantic meaning, with a map[T]bool it’s not obvious from the type alone that we only care about the keys, not the values.
Re:Go 1.18 by thegeekpirate on Wednesday March 16, 2022 @03:36AM (#30696228)
> with a map[T]bool

This takes up unnecessary space—use map[T]struct{} instead, which also explains to anyone reading the code that the value isn't used.

Re:Go 1.18 by randomswede on Wednesday March 16, 2022 @04:50AM (#30696621)
There is a slight difference between the two. With a map[†]bool, you can do something like:

if myset[thing] { ... }

With a map[T]struct(), you end up with:

if _, ok := myset[thing]; ok { ... }

Sometimes, the saving in space is TOTALLY worth the extra verbosity. Sometimes, the slight clarity from "non-existent keys return the zero value" wins.

Re:Go 1.18 by thegeekpirate on Wednesday March 16, 2022 @05:58AM (#30696975)
You've also opened yourself up to bugs by allowing the map values to be "false".

Using a "set's" value in an if statement doesn't make sense either, compared to

    if _, exists := something[item]; exists { ... }
which is explicit regarding what's actually going on.

As Rob said, "Clear is better than clever." https://www.youtube.com/watch?v=PAAkCSZUG1c&t=875s

I also don't want to be hunting down whoever creates a map[T]bool and doesn't leave a comment explaining it's a set ;)

Hopefully we won't have to worry about it for much longer regardless, since I imagine we'll be using proper sets (with methods) some point in the near future.

Re:Go 1.18 by randomswede on Thursday March 17, 2022 @05:05AM (#30709069)
I would say that "exists in the set" is determined only and exactly by "mySet[thing]" returning true, not that there happens to be a key in the map.

But, that's one of those "requires extensive documentation" (and ideally, wrapping in a custom type and provide methods for checking and manipulating the set(s)).

Re:Go 1.18 by yencabulator on Friday March 18, 2022 @03:59PM (#30726813)
Now every range over your set is likely to be a bug. `map[T]bool` is simply a bad design to use.
Re:Go 1.18 by randomswede on Monday March 21, 2022 @09:37AM (#30753955)
How? Why? If you use the map[T]bool, you obviously need to pay attention to the bool value, even in a range. Whereas in map[T]struct{} you don't need to pay attention to the values.

In either way, even with that type of data type underlying a set, I would (probably) provide a functional API to interact with it.

Re:Go 1.18 by yencabulator on Tuesday March 22, 2022 @11:19AM (#30767138)

    m["x"] = foo()
    for k := range {
        // if foo returned false, this is buggy
    }
Re:Go 1.18 by randomswede on Wednesday March 23, 2022 @05:11AM (#30776534)
Yes, as I said, if you use a map[T]bool, you need to use something like:

for k, v := range m { if v { } }

But it also allows you to use "if m[key] { ... }". It is literally a trade-off for what convenience you want. And in both cases, you should (probably) wrap an abstraction around the raw map.

Re:Go 1.18 by morelisp on Wednesday March 16, 2022 @05:52AM (#30696938)
Well, now there's no excuse for not having `myset.Contains(thing)` (though there really wasn't before either) which is even clearer.
Re:Go 1.18 by glenjamin on Wednesday March 16, 2022 @06:47AM (#30697258)
And now with generics we have a way to make this decision/optimisation once, and have everyone else benefit from it without having to be aware of the details!
Re:Go 1.18 by papageek on Wednesday March 16, 2022 @01:01PM (#30701305)
I wish this had been map[T]_ vs empty struct.
Re:Go 1.18 by fileeditview on Wednesday March 16, 2022 @03:39AM (#30696247)
You can also use a map[T]struct{}. I like bool better because of the default value behavior but struct{} is very clear and does not take extra memory.
Re:Go 1.18 by dimgl on Tuesday March 15, 2022 @06:59PM (#30693065)
Disclaimer: I'm extremely happy that generics are coming to Go.

> I wish I understood how people can say 'this will result in so much more weird boilerplate garbage code'

It's pretty simple: there's a lot of developers that misuse/shouldn't use generics.

Here's an article I found just casually browsing on Google that shows why this can turn out to be such a huge problem.

https://itnext.io/golang-1-18-generics-the-good-the-bad-the-...

Re:Go 1.18 by munificent on Tuesday March 15, 2022 @07:17PM (#30693221)
There's a lot of developers that misuse/shouldn't use any powerful feature. If the solution is to give them a nerfed language, then you also nerf it for the users that would use the feature well in productive, useful ways.
Re:Go 1.18 by jshen on Tuesday March 15, 2022 @08:20PM (#30693698)
Yes, it’s a trade-off. In an organization with thousands of developers the right trade-off is likely different than an org with 20.

What I don’t understand is why people insist on making Go like every other language that already does what that are looking for. You want a language with generics, purely functional blah blah blah, great there are tons of choices, use one of them. Why insist on reducing the diversity in language choice, and trade-offs?

Re:Go 1.18 by saurik on Tuesday March 15, 2022 @09:59PM (#30694393)
This is what policies are for, not entirely new languages: if you don't like generics and don't trust the end developers at your organization to not use them in stupid ways you should maybe (I say "maybe" as this problem just seems so lame of a problem to have: if your army of end developers can't be trusted then you should fire them and hire some real developers) have a way to turn off generics that isn't "use a language that doesn't support them at all" (which I will note is itself nothing more than a policy decision anyway).
Re:Go 1.18 by jshen on Wednesday March 16, 2022 @12:33AM (#30695347)
I’m not talking about generics specifically. I’ve been coding for decades. Go is by far the easiest language I’ve used when it comes to jumping into an arbitrary code base and making sense of it.

Again I ask, why insist that go become the same as all the other languages when you can just use one of those? Why demand less diversity?

Re:Go 1.18 by pie_flavor on Wednesday March 16, 2022 @11:38AM (#30700130)
Which part of this is not generalizable to literally every conceivable complaint about a language whether it makes sense or not? Why would I want diversity between languages where you do have to copy-paste lots of boilerplate, and languages where you don't? If there was a good, simple-in-the-Go-way solution to this problem other than generics, feel free to suggest it, but repeating 'why care about anything ever' is just pure noise.
Re:Go 1.18 by jshen on Wednesday March 16, 2022 @02:36PM (#30702370)
As I've said, this isn't about generics specifically. There are a whole lot of us who find Go code bases far easier to read and understand that most other languages. We believe there is a value to the language's simplicity, and we want to keep it that way. We've written Go for years, and haven't missed many of these features you want. In fact, we think there is a decent chance that Go code bases are easier to jump into and understand BECAUSE of it's simplicity.

You have many many choices that work the way you want. Go use them, why try to dictate to us that we can't have the choice we want? We disagree about the value of these things, and their trade-offs. That's what diversity is for, you have languages that work your way. Why insist that one of the few that doesn't has become like all the others?

Re:Go 1.18 by pie_flavor on Wednesday March 16, 2022 @03:46PM (#30703147)
You are posting a criticism of the feature, in response to a comment that is an answer to that criticism.

If your code did not use generics, it can continue to not use generics. If you did not interact with any libraries whose need for generics was apparent, you can continue to do that too and the libraries you were using aren't going anywhere.

But just because you don't interact with a problem doesn't mean it doesn't exist, and the problem has historically been solved with dynamic downcasting, code generation, or copy-pasting, all of which result in codebases far harder to read and understand than most other languages. For these problems, you are not trading off generic code vs simple code, you are trading off generic code vs incomprehensible code. It is great that you have never needed a tree-map instead of a hash-map, but many have.

Go's simplicity is in many ways it being the spiritual successor to C, and even C has generics nowadays because they are an enormous value add.

Re:Go 1.18 by jshen on Wednesday March 16, 2022 @04:17PM (#30703497)
You’ve missed the point. There are trade-offs that you are ignoring. There is no hard science that proves either of our opinions are right. I believe diversity is the better path in the face of such uncertainty, I don’t understand why you are against diversity here, and you continue to not directly answer that question.

“ If your code did not use generics, it can continue to not use generics. If you did not interact with any libraries whose need for generics was apparent, you can continue to do that too and the libraries you were using aren't going anywhere.”

This shows a profound lack of understanding of software development at scale.

Re:Go 1.18 by pie_flavor on Thursday March 17, 2022 @12:28PM (#30712961)
Of course I'm not directly answering a polemic gotcha. If I work in Go, and I have a pain point in Go, and I want that pain point to be addressed, that's not being 'against diversity' or being 'for diversity'. It is being against wasting lots of time for nothing. Why are you against productivity? You continue to not directly answer that question.
Re:Go 1.18 by jshen on Thursday March 17, 2022 @04:37PM (#30715614)
Unlike you, I’ve answered your question many times. You are only looking at the benefit for a narrow use case without accounting for its holistic costs. We have a difference of opinion about those costs, and there is no hard science that can prove either of us right. I have acknowledged your point of view, and the possibility that it could be right. You have not reciprocated in any way, or even acknowledge that you understand the point I’m making.
Re:Go 1.18 by pie_flavor on Thursday March 17, 2022 @08:52PM (#30717510)
Diversity doesn't have anything to do with holistic costs. You shift between whether you're talking about holistic costs and whether you're talking about diversity depending on which part of the point you're making.

https://en.wikipedia.org/wiki/Motte-and-bailey_fallacy

Re:Go 1.18 by jppittma on Wednesday March 16, 2022 @10:03PM (#30706734)
Can't you and yours just freeze at go 1.7? That way, you get your diversity. Pretend every code base that's using go 1.8 is using java or something. A lot of us who write go everyday think generics aren't complicated and are tired or repeating ourselves.
Re:Go 1.18 by jshen on Wednesday March 16, 2022 @10:30PM (#30706955)
This shows a profound lack of understanding of software development at scale. Also, as I've said many times in the thread above, I'm not talking about this specific implementation of generics.
Re:Go 1.18 by munificent on Wednesday March 16, 2022 @04:50PM (#30703909)
> why insist that go become the same as all the other languages

You're arguing a strawman. No one insists that Go become the same as all the other languages (which are themselves nowhere near the same as each other). People are just asking for generics.

C++, Java, C#, and Haskell all have generics and are still wildly different languages even with respect to their approach to generics.

Re:Go 1.18 by alex_sf on Wednesday March 16, 2022 @02:12AM (#30695841)
Policies don't work. It's why we lean on process in fields where correctness matters, e.g. aviation.
Re:Go 1.18 by reegnz on Wednesday March 16, 2022 @06:13AM (#30697052)
Policies do work if you have a process to enforce those policies. Without policy how do you define the process? "Good intentions never work, you need good mechanisms to make anything happen." http://nickfoy.com/blog/2018/4/7/good-intentions-dont-work
Re:Go 1.18 by alex_sf on Wednesday March 16, 2022 @10:37AM (#30699365)
By designing systems that encourage or enforce the correct action.
Re:Go 1.18 by alophawen on Tuesday March 15, 2022 @10:44PM (#30694722)
I predict someone will boil up a linter tool that would block generics in your CI.
Re:Go 1.18 by majewsky on Wednesday March 16, 2022 @05:57AM (#30696969)
I also predict it will be practically useless since those five libraries that you absolutely depend on will all be rewritten to take advantage of generics, and then you're left with the lose-lose situation of "maintain a fork of the last non-generics version myself" or "get stuck on the last non-generics version and never receive security updates again".
Re:Go 1.18 by alophawen on Wednesday March 16, 2022 @06:18AM (#30697075)
Not sure why you would run checks on your dependencies rather than your code.
Re:Go 1.18 by pjmlp on Wednesday March 16, 2022 @02:28AM (#30695911)
Because in many shops IT decides what languages people use, given the platforms, not devs.

Also quitting the job isn't always an option.

That is why some of us have to put up with languages that we rather not.

Re:Go 1.18 by throwaway000811 on Wednesday March 16, 2022 @05:26AM (#30696815)
We change the language; people who formerly enjoyed the language now have to put up with a language they rather not. Their only option is to quit programming since there are no programming languages they enjoy left.
Re:Go 1.18 by pjmlp on Wednesday March 16, 2022 @06:04AM (#30697004)
Or they become adults and acknowledge programming languages are products like anything else and they either evolve or stagnate.

Even COBOL and Fortran keep up with modern times!

Yes, including generics.

Re:Go 1.18 by jshen on Wednesday March 16, 2022 @07:23PM (#30705463)
C has entered the chat
Re:Go 1.18 by jppittma on Wednesday March 16, 2022 @10:05PM (#30706754)
Go 1.7 is still around. If people can still run python2, by all means, keep fighting the good fight.
Re:Go 1.18 by erik_seaberg on Wednesday March 16, 2022 @05:11AM (#30696738)
This. I joined a Java- and Scala-centric team, yet Go is continually harder to avoid for no fault of our own, so I’m glad we’ll at least have a less obstinately broken dialect.
Re:Go 1.18 by jshen on Wednesday March 16, 2022 @11:26AM (#30699981)
So you want to diminish the diversity in programming languages because it’s an inconvenience to you personally. I respect the honesty.
Re:Go 1.18 by pjmlp on Wednesday March 16, 2022 @11:31AM (#30700054)
Thanks, the same way that people in Go community see as inconvenience to learn how to write better code.

The old ways of code generators are good enough.

Re:Go 1.18 by jshen on Wednesday March 16, 2022 @02:41PM (#30702413)
I've been coding for decades. I've written large scale systems in functional languages. I was a believer, but after many years of experience, I didn't find it to add a whole lot of value. I didn't find that there were fewer bugs as promised, it wasn't faster to develop and ship features, and most importantly, it was hard to jump into other peoples code and make sense of it.

You might have a different opinion, that's fine, you have tons of languages that work the way you want. That's what diversity is for. Yet so many of you want to remove that diversity for a reason that I don't understand. There is no science that has proved which of us is right, so the best option in my opinion is to let diversity flourish. I can't understand why you all are against that.

Re:Go 1.18 by pjmlp on Wednesday March 16, 2022 @05:18PM (#30704217)
Apparently the Go team has themselves admitted that we are right and they were wrong.

Go is open source, create your own fork without generics and lets see which version keeps going.

Re:Go 1.18 by jshen on Wednesday March 16, 2022 @05:42PM (#30704492)
We must be talking past each other, and maybe we don't disagree all that much. I'm not talking about generics in this form, and I think the Go team did a good job in their approach and implementation. However, you can read in this thread many people that are demanding more, specifically with the generics implementation. It's not good enough because you can't create monads, do purely functional programming, etc.

I'm hopeful that this implementation is hitting the sweat spot, and that the Go team won't chase the demands to make Go like many of the other languages. I think the biggest win for Go is not having class based inheritance. Fortunately, I haven't seen anyone demanding that.

Re:Go 1.18 by kitd on Wednesday March 16, 2022 @04:25AM (#30696504)
The syntax isn't the only driver of language popularity. Ecosystem/ tooling/ major sponsors/ large precedent projects etc all enhance a languages adoptability and big shops want to pick a language with a low risk and large supply of coders.
Re:Go 1.18 by alex_sf on Wednesday March 16, 2022 @12:46AM (#30695424)
That was one of the goals and virtues of Go imo; the language was nerfed. It made the hard things easy, and prevented the really hard things from being implemented in silly ways.
Re:Go 1.18 by closeparen on Wednesday March 16, 2022 @04:50AM (#30696617)
It guarantees that when people do things in silly ways, their silliness is splayed across so many characters and lines that you'll never have the time to change an appreciable portion of them.
Re:Go 1.18 by fulafel on Wednesday March 16, 2022 @05:21AM (#30696795)
Languages are very powerful in shaping expression of programmers, new and experienced. Limiting expressivity is how we eg got from assembly programming to structured programming. Same memory safety, garbage collection, etc..
Re:Go 1.18 by ta20200202 on Tuesday March 15, 2022 @07:49PM (#30693483)
> there's a lot of developers that misuse/shouldn't use generics.

The same is true for other features, like channels and goroutines.

Re:Go 1.18 by pstuart on Tuesday March 15, 2022 @08:35PM (#30693814)
Over use of channels is new Go coder smell. I certainly was guilty at the beginning.

But goroutines? I see much less abuse there. And they're so damn handy.

Re:Go 1.18 by metadat on Tuesday March 15, 2022 @07:56PM (#30693532)
Goroutines and channels seem comparatively simple compared to the representational symbolic changes involved with generics, which make the code look and read more like Greek. The beauty of Go is (was) largely in its simplicity and python-esque (or maybe better than python) readability.

With generics, reading and reasoning about code becomes [even] more challenging.

Personally for me, at this juncture I'm finding that for new projects I might just as soon spring for Java or maybe even prefer it to Go. For the straightforward mvn-style dependency management, if nothing else.

It's all moot now, though. There's no going back, this puppy is cooked!

Re:Go 1.18 by alophawen on Tuesday March 15, 2022 @10:38PM (#30694688)
I spent 4 months in '21 rewriting a golang backend to properly use channels for concurrency. The previous developers did misuse it and left a steaming pile for me to find.

However contracting pays well, so I don't care.

You might want to reflect on your reasons for jumping ship because your tooling gained a new feature. Sound's rather irrational to me.

Re:Go 1.18 by alex_sf on Wednesday March 16, 2022 @12:45AM (#30695413)
It's less that it gained a new feature, and more (the fear at least) that it made a change for the worse.

Avoiding updating to a new version of OSX that stabs you in the face is a reasonable thing to do, despite it being a new feature.

Re:Go 1.18 by baby on Wednesday March 16, 2022 @05:03AM (#30696688)
Exactly. I work with rust and ocaml all day long, but reading a Golang codebase in contrast has always been such a pleasure because it’s just so easy to read. I hope generics don’t change that. There was really nothing like Golang out there.
Re:Go 1.18 by lenkite on Wednesday March 16, 2022 @05:46AM (#30696917)
Go already had generic structures anyways. Go maps supported generics. Or did you always use map[interface{}]interface{} everywhere for the purity of your anti-generics position ?
Re:Go 1.18 by alex_sf on Thursday March 17, 2022 @01:33AM (#30707995)
The built-in types that supported generics were limited to the essentials; slices, arrays, maps, etc. Those basic building blocks were obviously sufficient to allow Go to reach the level of success it has. It's not an argument to allow for unlimited generics.
Re:Go 1.18 by alophawen on Wednesday March 16, 2022 @06:25AM (#30697113)
I think this line of reasoning is detrimental for yourself:

- noone is forcing you to use generics in your go programs.

- if you are running outdated OS because you don't like some UX change, you might as well consider changing OS.

Re:Go 1.18 by metadat on Wednesday March 16, 2022 @12:23AM (#30695294)
It's more about the direction and trajectory, Go used to be fun for me but the appeal has waned.

Sounds like it's just me.

Re:Go 1.18 by rr808 on Tuesday March 15, 2022 @10:26PM (#30694600)
My view is there should be official libraries with generics, but regular developers shouldn't be allowed to write any.
Re:Go 1.18 by bashery on Wednesday March 16, 2022 @07:08AM (#30697387)
agree +1
Re:Go 1.18 by preseinger on Tuesday March 15, 2022 @07:07PM (#30693135)
Problems are not generic. "I need a N-ary binary tree over arbitrary comparable types" is not a problem. Problems are expressed in terms of domain concepts that are unique to the problem space, the organization, the business need. Some _implementation details_ or maybe patterns that can be used to solve those problems may be generic. That's separate.
Re:Go 1.18 by codeflo on Tuesday March 15, 2022 @09:02PM (#30694024)
That’s true, a binary tree isn’t a problem, it’s a tool for solving a certain class of problems. Since you can’t build reusable tools in pre-generic Go, (and, to be honest, only a limited set of tools with Go’s new generic system), programmers are forced to reinvent half-baked ad-hoc solutions all over their code base. I once read an article about a C codebase that contained dozens (!) of specialized linked-list implementations. Large Go codebases, from everything I’ve seen, aren’t all that different.
Re:Go 1.18 by hodgesrm on Tuesday March 15, 2022 @10:00PM (#30694398)
Specialized collections are not necessarily bad. ClickHouse has dozens of hash table implementations, each tuned to a specific use case. It's what you do when you need something to go very fast.
Re:Go 1.18 by jen20 on Tuesday March 15, 2022 @11:50PM (#30695122)
Several specialised implementations of a concept with different algorithms is quite different to several implementations of the same algorithm because the language does not support their reasonable reuse. Rust gives you “specialised collections” via monomorphisation.
Re:Go 1.18 by lanstin on Tuesday March 15, 2022 @10:32PM (#30694643)
And that is the exact joy of using a language like C or Go; you need to sort your things, just add in two pointers and make it a list you sort on. Eight or now sixteen extra bytes and you have a good tuned data structure. I don’t want to use a bunch of generic structures, I want to use the ones that solve my particular use case best.
Re:Go 1.18 by eternityforest on Wednesday March 16, 2022 @05:06PM (#30704102)
I always say "Just right is all wrong". The time and standardization cost is often just too much for the small gains. I'd much rather have everything be reusable, abstracted, and one size fits all, aside from the tiny fraction that matters enough to optimize.
Re:Go 1.18 by lanstin on Wednesday March 16, 2022 @11:32PM (#30707372)
Good points. But for myself, I like it when the structure of the code and data structures exactly fit the need. Like the old quite, “show me your header files and hide the C files, and I will understand your program.”
Re:Go 1.18 by nine_k on Tuesday March 15, 2022 @08:38PM (#30693832)
Some problems are technical problems, posited and solved by engineers.

Solving them helps better solve the product and business "real-world" problems.

Re:Go 1.18 by rtpg on Wednesday March 16, 2022 @12:39AM (#30695378)
I mean Go has map right?

"I need a priority queue for X" isn't generic, and "I need a priority queue for Y" isn't generic either. But well if you're doing it a lot, would be nice to not just reproduce the same bugs over and over again, yeah?

Everyone's worried about Go turning into Java and I can't speak too much to the utility (I have written maybe 50 pages of go in my life) but anyone who uses Python's standard lib can point you to 10 different things that are nice to have bug-free versions of and that "just work" thanks to Python's "generics".

Re:Go 1.18 by lenkite on Wednesday March 16, 2022 @05:47AM (#30696922)
I guess you used map[interface{}]interface{} everywhere you needed to use a Go map ? If not, then your statement is a logical contradiction.
Re:Go 1.18 by preseinger on Thursday March 17, 2022 @04:17PM (#30715434)
Of course not. I use map[myKeyType]myValueType, depending on the problem I'm solving.
Re:Go 1.18 by viraptor on Wednesday March 16, 2022 @09:21AM (#30698451)
It depends on the level of abstraction you're addressing. One level may be "i need to store things with a quick search function", another may be "i need a storage of ordered names and expiry date for things", etc until you get to "I need a binary tree which orders by comparable types".

Where you split that process as a separate library you either decide to write or reuse - that becomes the problem to solve. A set implementation may be a problem to solve: https://github.com/deckarep/golang-set A btree may be a problem to solve: https://gitlab.com/cznic/b/-/tree/master/v2

Re:Go 1.18 by diehunde on Tuesday March 15, 2022 @11:27PM (#30695011)
Go is used a lot for systems programming where you do see those problems.
Re:Go 1.18 by john567 on Wednesday March 16, 2022 @04:53AM (#30696635)
No you don't.

If you do, you haven't understood the problem that you need to solve and you are reaching for things you don't need to use.

Re:Go 1.18 by diehunde on Thursday March 17, 2022 @10:43PM (#30718231)
Seems like you are not aware of the kind of problems they solve. Systems engineers have been writing generic programming code for years to build databases, message queues, file systems, etc where you do need data structures that support arbitrary types/functions.
Re:Go 1.18 by jchw on Tuesday March 15, 2022 @10:56PM (#30694822)
It’s not a satisfying answer, but the truth is that there just isn’t that much Go code out there suffering from a lack of the kind of basic generics being introduced. It exists, but it’s not the norm.

Instead, what is likely to happen is, a lot of problems that generics can be applied to, they more often will be, simply because the option is on the table, regardless of whether it really improves anything. Go taught me to stop worrying and trust the For loop, and now we’re probably going to have dozens of utility libraries with Map and Reduce routines that people will use for extremely simple loops that don’t need them, probably resulting in slower code that takes longer to compile that needs a slower and more complicated optimizer to make up for it. In my opinion, the antithesis of what makes Go great.

Not saying generics is all bad, or that reduce is bad, or anything like that. But once a programming language has a new way to do something, you can be damn well sure people will use it, often even to their own disadvantage. Go doesn’t have pattern matching control flow, so the best degree of soundness you can pull out of an Optional type is ugly visitor-pattern type interaction. And yet, I’m worried routines will superfluously return Optional types anyways, just because you can, even though it’s not really any better than just returning a type and a boolean.

And yes. Actual code that actually needs generics for real will benefit, undeniably. Data structure and generic algorithm implementations will benefit greatly. The ugly sort package can finally be cleaned up. That’s great. But, most Go programs simply aren’t suffering from a lack of basic generics. Operative words: most, and basic generics. Many programs simply don’t need any data structures other than a basic growable vector type and a basic hashtable, and Go has both and they are built-in and work generically. Yet the more complex problems that C++ templates and Rust generics solve will probably not be aided at all by Go generics, which are simply much more limited in scope.

And despite that, this is quite an increase in compiler complexity. I know many are thinking “how hard could it be? Tons of languages do it today”—but Go isn’t really like all of the other languages. The simpler compiler is a huge benefit to the compiler and the whole ecosystem. Arguably, Go’s simplicity enabled them to experiment with things that wouldn’t be very easy to do in other languages, with regards to its GC and threading model. They’ve got it figured out of course, but it really isn’t a simple walk in the park. Any single aspect has a lot going on:

https://github.com/golang/proposal/blob/master/design/generi...

My hope is that the relatively mature ecosystem of Go will somewhat encourage people to keep their code simple and use generics sparingly, but with such a major shift in the language it’s hard to imagine what is “idiomatic” won’t change over time. I feel Go’s brutalist simplicity is its strong point and that it will just be an inferior option if you try to write code in it like C++ or Rust.

Of course… we’ll see.

Re:Go 1.18 by pie_flavor on Wednesday March 16, 2022 @11:58AM (#30700431)
I really, really try to ignore my own impulses on Go simplicity, because I don't understand it and lots of people who say they do understand it are prone to saying the same things which are different from the things I say, so there is clearly an Outside View to take. But I cannot help but view this as a case of special pleading. You have this great spiritual successor to classic C, and then there's also channels tacked on, with native syntax, that are the least pain-in-the-ass solution to standard problems like iterators. So you get lots of people using channels like iterators. This is a problem at several levels, but I never see anyone complaining about it - not even Go's detractors, who are instead focused on where the stdlib shunts its complexity to. Repeat for a few more idiosyncrasies. Even the basic collections are guilty of this - how many people use an explicitly deduplicated array, or a hash table to struct{}, when what they want is a set?

The problem you're describing already exists, there's no preventing it or getting rid of it, and generics are tame by comparison - at least they semantically mean exactly what the developer intended them to mean, don't come with non-obvious performance downsides, and don't clobber existing concepts like error handling.

As for optionals vs separate bools, love 'em or don't, but yes, there is a downside, which is in my view possibly Go's only regression from C: no longer being able to stick the function call in the if-statement directly without additional fanfare.

Re:Go 1.18 by jchw on Wednesday March 16, 2022 @01:23PM (#30701536)
I don’t think Go channels really panned out well. However, I do think that Go’s thread model and scheduler have turned out great. I think channels could’ve made sense, but they wound up being both more complicated to use and less performant than I think was hoped for. However… channels aren’t a solution for iterators. They’re a solution for communicating between threads. Go, like C, simply doesn’t have anything geared towards solving the problem iterators solve. Superficially they can fulfill some similar needs, but personally I feel they’re both practically and philosophically not in tune with that use case, even though you can certainly make it work in some cases to surprisingly decent effect.

Now as for the rest. Generics don’t automatically make code slower. In fact, in some places, the practical effect should make code faster; for example, the sort package currently defeats escape analysis even though it shouldn’t, and a monomorphized version should not suffer that consequence. Also, obviously, the fact that it removes runtime dispatch will also lower overhead. I understand that.

However, generics DO have some consequences:

- Every part of the toolchain—the compiler, linters, etc.—needs to understand generics and handle them properly. This is a non-zero cost; generics-heavy code will have measurably slower compile times. Go compilation times are fast, and that’s a feature.

- Generics improve the ergonomics of certain patterns that are absolutely slower. It is totally possible for someone to write a “map” function today for every type they could ever want, but it’s not really practical, and since it forces you to just write the loop out anyway, it really begs the question why you would bother in most cases. With generics, it should be relatively easy, but without aggressive optimization, it will be less efficient than the simple For loop. The map call and closure would need to be inlined for the optimizer to be able to get back to the same point. Having to do this, again, will slow down compilation more.

Honestly, you’re right; it’s far from the end of the world. However, I am pessimistic because to me, it’s unclear the costs of generics will be outweighed by the benefits of generics, but once the cat is out of the bag, it’ll be hard to ever go back on it.

Personally, I believe there are other improvements that would’ve been more valuable to consider first, like, personally, sum types and basic pattern matching. Sum types feel like something that, while it would have costs, has a potential to benefit a wide variety of programs and make certain code less error prone in a way that I don’t expect generics to.

Re:Go 1.18 by pie_flavor on Wednesday March 16, 2022 @04:05PM (#30703355)
Sum types are indeed great. That's why they're in Go 1.18. Pipe syntax and all.
Re:Go 1.18 by jchw on Wednesday March 16, 2022 @04:11PM (#30703428)
As far as I know, that’s only for interfaces, and it’s more like a union and not a sum type. I’m talking about sum types for structs, like Rust has with enum.

(I realize I’m replying ridiculous fast here, but I just happen to click over to Comments on the first minute. Dumb luck.)

Of course, I could just use Rust, but it’s much harder to make idiomatic Rust libraries than it is idiomatic Go libraries, and I think that fact stunts the ecosystem a bit.

Go may encourage you to use a map to an empty struct for a set, or a weird if statement syntax that contains a full statement instead of a more elegant looking match or for expression, but I find its little quirks to be manageable and without a terrible amount of consequence. Generics will probably bring some good, like the end of needing weird slice tricks, but I’m still concerned it won’t be overall worth it.

Re:Go 1.18 by dragonwriter on Wednesday March 16, 2022 @04:22PM (#30703548)
Go has (untagged) union types, not sum (tagged union) types.
Re:Go 1.18 by throwaway894345 on Tuesday March 15, 2022 @08:34PM (#30693802)
> I wish I understood how people can say 'this will result in so much more weird boilerplate garbage code'

Who says this? There have been a lot of weird arguments surrounding Go and generics over the last decade, but I’ve never heard anything like this.

Re:Go 1.18 by squeaky-clean on Tuesday March 15, 2022 @10:31PM (#30694633)
As a non-Go user who peaks into threads about major Go updates, this is one of the most commonly repeated things I've read.
Re:Go 1.18 by stouset on Tuesday March 15, 2022 @11:03PM (#30694872)
It's a point that's been made repeatedly as comments on this very article.
Re:Go 1.18 by pie_flavor on Wednesday March 16, 2022 @11:59AM (#30700446)
It's a point that's being made in a different reply chain to the post, in fact.
Re:Go 1.18 by randomdata on Wednesday March 16, 2022 @12:30AM (#30695331)
I don't know who is saying it, but you can certainly find GitHub repositories of people who have been playing around with generics creating it. Presumably it is people being silly or playing around to see how far they can push the feature under experimental conditions, but developers have also been known to unfathomable things in real code, so I can kind of understand the sentiment. Channels lead to a lot of weird and garbage code when they were new and shiny, when developers felt they should use them for the sake of using them, so the idea isn't unprecedented either.