Earlier quoted context omitted.
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 adv…
> 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.
Go 1.18
531–540 of 614 posts
Re: Go 1.18
#532Earlier quoted context omitted.
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.
It's a point that's been made repeatedly as comments on this very article.
Re: Go 1.18
#533Earlier quoted context omitted.
Ergonomics sucked and a lot of people didn't use them (or even know they existed!) because ergonomics sucked
From my work experience at the time, it was used pretty heavily in new codebases.
Re: Go 1.18
#534Now Go has everything I need in a programming language!
Not for me. There is no ?: ternary operator. Having to write 6 additional lines of code for each tiny conditional sucks. It's not frequent, I think I've only had a single case in a few years where I had difficulty working around, but when it happens - it's not fun. err := h(cond(x) ? f(x) : g(x)) vs var temp T if cond(x) { temp = f(x) } else { temp = g(x) } err := h(temp) Hopefully, this can be improved with generics…
var temp func(x) T = g
if cond(x) {
temp = f
}
err := h(temp(x))Re: Go 1.18
#535Earlier quoted context omitted.
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.
You could just do `defer if shouldDoSideEffect { something() }`
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
#536I highly recommend checking out the Type Parameters Proposal[1]. It's surprisingly easy to digest and has more realistic and complex examples than the quickstart guide or any other blog post out there. [1] https://go.googlesource.com/proposal/+/refs/heads/master/des...
Re: Go 1.18
#537Earlier quoted context omitted.
I legitimately cannot spot the bug. Can you write out the equivalent Ruby code in Go pre-generics? I really did try but I honestly cannot understand what your Ruby code is supposed to do. I don't know what select and take are supposed to do, and I can guess at reduce but the symbols in the method are utterly arcane to me. Does Take grab exactly 20 items or does it do something like nums[:21]? Depending on how Take is…
The code is equivalent, except the golang version accidentally loops an extra time. `&:meth` is just Ruby syntax for "a function that calls the `meth` method on its argument". So `&:foo` is shorthand for `func(x) { x.foo }`. `take(n)` just returns the first `n` elements. `select(fn)` iterates for every element for which the function passed to it returns true. `reduce(fn)` combines the previous iteration with the resu…
I was reflecting on this and the one language where I don't feel this way is SQL. I'd consider it my strongest language, and it's an extremely functional language. I have no trouble deciphering complex SQL, but it takes me an enormous amount of time to figure out what happens in those long function chains in general purpose programming languages. I'm not sure what it is about SQL that makes me feel this way, but maybe it gives some hint why our brains seem to work in different ways?
Re: Go 1.18
#538Earlier quoted context omitted.
Kafka is currently undergoing a rewrite into java.
Indeed. To add further it is also facing competition from Apache Pulsar and NATS. Not to forget Redpanda a Kafka rewrite in C++.
Re: Go 1.18
#539Honestly I think this will make the overall programming experience worse.
In what way? Almost every other major language has them without major issues. Go devs saying generics are a bad thing reminds me of people in Oregon freaking out over being allowed to pump their own gas while the other 49 states have been doing that for decades.
Re: Go 1.18
#540Earlier quoted context omitted.
Replace in go.mod breaks `go install`?
Oh yeah, this used to work but some go version ago it stopped working. See https://github.com/golang/go/issues/44840
for the record it stopped working in go 1.15. 1.14 was the last version it worked in.