Folks, we love that you comment, but as a reminder, please keep your comments civil, and always aim to add to the discussion. If you have nothing to add to the discussion, please refrain from commenting. Otherwise it takes a lot of effort to moderate the comments.
After my firm moved a not so trivial sized code base from C++ to Go, I can say that in my very humble opinion Go got a whole more right than wrong. the team that created Go (including, but not limited to, Rob Pike and Ken Thompson) are the giants that we stand on the shoulders of. When designing the language, it appears to me that they made design decisions based on first principles. Taking influences from C and Modula-2 was (again, in my very humble opinion) as opposed to object oriented languages created a language that didn't have the baggage that comes along with it.
So I went on Wikipedia to refresh my knowledge of all the amazing things this man did for the software industry, and I realized he looks two decades younger than he actually is. Way to efffin go, Rob!
Lack of generics early on has created a lot of undesirable legacy code in the Go projects I encountered: * Excessive `reflect` package with `any` * Using text template to generate Go code * Using AST to generate Go code All of these should be rewritten with generics, but there are 50,000 lines of them.
If it works, it works. Generics in my opinion was one step forward to all feature bloat we see in other programming languages. I wish the Go team won’t introduce to many features in syntax like Rust team did. So the language hasn’t had at least 3 ways to do one thing.
@@nas337 I just described 3-4 ways of doing the same thing though. Witty engineers are going to abuse the lack of features by using outside tools (e.g. codegen, preprocessor), just as they do in misusing language features if the language has a bloat of features.
@@RicardoSilvaTripcall There are a bunch of reasons * codegen is not available for linter / code search / bug analysis tools / test coverage analysis * codegen is difficult to understand and difficult for devs to update going forward. Rewrite would have to be weighted against other priorities, of course. So except for mission critical code, would likely not be done at most shops.
In the concurrency example at 13:20 if timeout happens, goroutines that didn't complete will be stuck, as writing to the channel will be blocked forever.
Yeah good point, should've been a channel of capacity 3. I think this example is flawed in more ways than one, e.g. it doesn't use contexts, so the other queries aren't cancelled after a timeout, etc.
If they admit Go2 is an eventuality or even a remote possibility, Go dies. No one will want to build knowing theirs a time bound on the future of their platform, unless they agree to a huge future migration effort.
@@YuriyNasretdinov except for your non-GO dependencies Zig can crosscompile well even C and C++ stuff for you (you can just use it as a C/C++ compiler dropin) because of that one company has a contract with the Zig foundation to keep this well maintained for their Go dependencies
@@leggysoft I was explicitly commenting at the cross-compilation situation here. And guess what, Zig also brings its ease of cross-compilation to C and C++ (because it has that builtin).
after the citation of ousterhout I wen to look at the threads paper, and to me it seems ousterhout is still right, and pike got ousterhout's message wrong (just look at the conclusion slide), pike's own admission of "doing concurrency like things sometimes without even realizing it" is a problem and in agreement with ousterhout (but then, of course, he later goes on to talk exactly about the problems ousterhout stated ...)
Would be interested to hear more about introducing sum type (ie Rust style enum, or Haskell style data declarations). Especially around error handling using Option/Result sum types to handle nil/error values, along with some syntax to “bubble up” errors out of a function like Rust ? operator. I die a little bit every time I see any non trivial go code, and > 50% of the line count is `if err != nil { return err }` “But you should be explicitly handling errors!” Is the usual go community apology. Sure, if you actually handle them. If you’re just returning them for calling code to do something with them (probably just check for nil and return them again), that’s not “handling” them. And having nil at all is just a massive footgun that could have been eliminated. Then go doubles down on nil by having typed nils, so there are a bunch of edge cases where nil != nil. It’s like they heard nil was a billion dollar mistake, and said “You know what? Let’s aim for a TRILLION dollars!”
BTW rust/haskell Option is awful from composing and keep interfaces stable perspective. Most code keeps defensive stance and makes function arguments and results Optional to keep compatibility in case of requirement changes. You can't add or remove optionality later without code breaking especially for libraries. Zig at least allows to keep stability on T -> Optional argument refactoring.
@@doBobro I don't know any Zig, so if the argument T turns to Optional and receives "Nothing", will the function return error? Or simply panics? Maybe somehow Zig will pick a default value?
@@doBobro Oh, you are saying that all the call sites of the function don't have to change, so it's kind of like "Type *" (i.e. pointers) in C, but the function receiving an "Type *" has to deal with it probably being NULL?
@@doBobro But what about u64 -> Optional? Before, the caller just passes any u64, so the raw value of an Optional will be just that u64, than how can we distinguish Nothing and Something(value)? Will the Zig compiler automatically transform all u64 at the call sites into e.g. (true, u64_val)?
Honestly some of the go docs are still awful. Not as bad as a lot of the package documentation for a lot of packages like the AWS SDK for Go but that's not the Go teams fault
I am shocked, what kind of audience was that? Bunch of students apparently with no exp. They can't even form a question for this man. Arenas was a good question, i would ask that since I think they are cool, but as he mentions, very dangerous if not done correctly.
26:54 Indeed, go's module system is it's one of the worst sides of it. It's way more better how node.js and rust handles that, when i struggle to understand go's module system i've experienced very big frustration.
Go's biggest sin is being only moderately better than Java. It's no wonder C++ still plays a big role at Google, because Java already took over where C++ would have otherwise been used. The remaining cases where C++ is still used would not be written in Go for the same reasons it wouldn't be written in Java. I do have to say that Go is quite a pleasant language to use when it comes to working with binary formats. Just the right amount of succinctness and type checking.
At the present moment (early 2024) Java is arguably in a better shape than Go. With the introduction of virtual threads in OpenJDK 21, there’s one less reason to adopt Go.
@@danvilela Go has a garbage collector -- which means it uses extra RAM just like Java does. Go introduced "goroutines", a threaded implementation of co-routines, but didn't solve the underlying problem of concurrency bugs. The only real benefit to Java users would have been the type system, but even there they didn't have generics until over 10 years later. As such, despite the initial excitement around Go, interest has petered out. It was never going to replace C++ because of garbage collection, and it didn't do enough to replace Java. It's a quirky language with a moderate following, and that's all it will ever be.
@@chrimony [speaking from web dev point of view] In real world scenarios java memory usage is much higher than go. In go you can really easy optimize memory usage, by using object pooling, which is not possible in java due to lack of out parameters (in libs / frameworks / std api). In java most of the frameworks doesn't care about object allocation, and you end up with massive memory usage. While I agree that java and go are simillar in the use cases, and java is more performant, in many ways, than go, the fact is that go ecosystem focuses on the performance, while java ecosystem focuses on the developer productivity (which leads to the configuration driven development) and often doesn't care about optimization, which leads to bloated software from the beginning. Java ecosystem lead to the generation of the developers, which doesn't understand anything about web dev, they just know how to configure framework of the choice.
The thing is, "we are boring on purpose" gets really old after a decade. Now it looks more like an excuse for intellectual masturbation or just laziness.. I really don't think it has much to do with backwards compatibility either, a lot of cool things can be done while still maintaining backwards compatibility. Theres been so much innovation in the languages world over the past decade. I'll even agree that most are bad ideas or not compatible with go but there are a few good ideas there and even some that a compatible with go.. if not copying, they should at least inspire some action or innovation..
@@jabuciI find swift to be incredibly hard to read, with too many features. Anyways, optional parameters can be implemented with pointers and a bit of godocs on top of the function to make sure people know what the params serves.
Baking telemetry into a programming language is a TOTAL NO GO. I would ditch the entire ecosystem and fallback onto ASM if all languages did that. Even those who assert that it is an opt-in should be scrutinized. Apparently they got paid by Ggl and speak on behalf of Ggl's interests. STOP SPYING STOP GLORYING BACKDOORS.
audience is so dead and clueless. god, there are so many questions, why making and working with dynamic libraries is so broken (still, 7? 8? years and counting), why not let people use the syntax that stdlib is using (for example creating a custom map type mymap[type]type that implements an rb-tree inside), what was the reasoning behind not allowing operator overloading and so on and so forth
Maybe you can clarify your question about dynamic libraries, I'm not sure what you mean. As far as the map syntax, you can use myMap[type, type] since 1.18, which most people would consider just as good (I actually think they should allow map[keyType, valueType] with the built-in map implementation, but that's another discussion.) I personally have never seen operator overloading used in a way that was clearer than named methods. Now to understand what >> does, for example, I need to figure out what types its operands are, then find the correct overload definition, when a well-named method just lets me read the LOC without digging into all of that. For a language whose design was largely driven by the principal of readability over tenseness, operator overloads seem to me like an illogical addition.
maps and slices are not stdlib features: they're part of the language itself. He mentions this during the talk as a bit of a wart, and something that might have been done differently if generics had been part of the original language design. If it does ever happen, it'll probably be in the form of mapping some of that special language syntax to something a regular Go type can implement, and moving those container types to the stdlib.
We highly welcome you to come to the next GopherConAU. We also provide travel assistance to speakers, so if you would so incline, you could put in a talk when the CFP opens. CFPs have a 4% acceptance rate so it's pretty high.
@@natea.2926For things like linear algebra as an example, operator overloading makes things MUCH more readable IMHO. Especially if you're in a higher level language anyway. I think the problem is when operator overloading doesn't come with guarantees (for the most part) as seen in ie C++ or Python. But in Haskell, if you see a
You should look "retrospection" up in a dictionary.. This is a very healthy exercise and what you say is absolutely true, which is why one needs to be aware of it when making such an analysis. I find it quite incredible, that your only contribution to a 40+ min video, is your take without any nuance. Also, I mean you are incredible as in not-credible.
Could you elaborate on that? Why is that? Do you think that golang is more race-condition prone than other languages and why? Also, would that be a problem in all languages that implement stackful coroutines with green threads or is it specific to go?
@@Y-JA Ousterhout wrote that threads are--not always, but *usually*--a bad idea. Rob thinks he has refuted John's paper in some way with goroutines and channels. From what I have seen in popular projects, goroutines, channels, green threads, etc have only served to strengthen John's argument, not weaken it. This is not specific to Go, but any "easy concurrency" language where people dash off threads without thinking carefully.
If Go had avoided accessing shared state from a different go routine, and forced all coordination via channels it would have gone a long way towards concurrent safety. As it is, you can do whatever thread-unsafe access to any data at anytime from anywhere, and you’re back in the same mess of having to hope mutexes and things are being used correctly (spoiler - they’re not being used correctly)
@@jasonstewart_kyYes, you can cause data races in Go, but the race detector is fast and easy to use in both unit tests and in e2e application tests. I do find races in my own code once in a while, but they are rare.
Folks, we love that you comment, but as a reminder, please keep your comments civil, and always aim to add to the discussion. If you have nothing to add to the discussion, please refrain from commenting. Otherwise it takes a lot of effort to moderate the comments.
After my firm moved a not so trivial sized code base from C++ to Go, I can say that in my very humble opinion Go got a whole more right than wrong. the team that created Go (including, but not limited to, Rob Pike and Ken Thompson) are the giants that we stand on the shoulders of. When designing the language, it appears to me that they made design decisions based on first principles. Taking influences from C and Modula-2 was (again, in my very humble opinion) as opposed to object oriented languages created a language that didn't have the baggage that comes along with it.
So I went on Wikipedia to refresh my knowledge of all the amazing things this man did for the software industry, and I realized he looks two decades younger than he actually is. Way to efffin go, Rob!
For me, the major bloopers are allowing naked returns and weak enums. Had my share of bugs mostly due to those two things.
33:26 Rob Pike describes telemetry of google chrome.
take a look at mobile phone keyboards - shock horror
Lack of generics early on has created a lot of undesirable legacy code in the Go projects I encountered:
* Excessive `reflect` package with `any`
* Using text template to generate Go code
* Using AST to generate Go code
All of these should be rewritten with generics, but there are 50,000 lines of them.
If it works, it works.
Generics in my opinion was one step forward to all feature bloat we see in other programming languages. I wish the Go team won’t introduce to many features in syntax like Rust team did. So the language hasn’t had at least 3 ways to do one thing.
@@nas337 I just described 3-4 ways of doing the same thing though.
Witty engineers are going to abuse the lack of features by using outside tools (e.g. codegen, preprocessor), just as they do in misusing language features if the language has a bloat of features.
Why rewrite something that would work exactly the same as before? Just for the sake of it?
@@RicardoSilvaTripcall There are a bunch of reasons
* codegen is not available for linter / code search / bug analysis tools / test coverage analysis
* codegen is difficult to understand and difficult for devs to update going forward.
Rewrite would have to be weighted against other priorities, of course. So except for mission critical code, would likely not be done at most shops.
@@voidvector in what way is codegen not available for source code analysis?
Nice to see a shout out on the gofmt slide
In the concurrency example at 13:20 if timeout happens, goroutines that didn't complete will be stuck, as writing to the channel will be blocked forever.
Yeah good point, should've been a channel of capacity 3. I think this example is flawed in more ways than one, e.g. it doesn't use contexts, so the other queries aren't cancelled after a timeout, etc.
Great talk. Thank you Rob.
Nice to see Rob being honest but I expected this talk to be about the Go type system. It's less than optimal. It misses Enums built-in.
Great talk, 14 years of progress
When seeing "Gopher" and and greybeard like "Rob Pike" in the title, I thought of the old Minnesota link-hierarchy server.
if you initialize a memory arena aren't you supposed to clean it up yourself instead of GC?
In Go the GC cleans it for you. What you do is say I’m not using the arena anymore. But the GC will do the cleanup
I'm glad he mentioned "Go 2" is no longer going to exist.
Go 2 considered harmful
If they admit Go2 is an eventuality or even a remote possibility, Go dies. No one will want to build knowing theirs a time bound on the future of their platform, unless they agree to a huge future migration effort.
@@EbonySeraphimYou mean like every other language?
@@Alex-lu4po yes, just like every other language that isn’t being discussed now.
@@EbonySeraphim but where should they migrate to then?
Is there any plan to fix what they got wrong?
Cross compilation is magic with Golang
I wish there was another (functional) language using go runtime.
Love listening to Rob.
8:50 While Go is great, I would argue that there another language which is even better at it: Zig
But then again, it's considerably younger.
Yeah the way Zig implements cross compilation is super neat. However Go's cross-compilation also works well unless you use cgo.
@@YuriyNasretdinov except for your non-GO dependencies
Zig can crosscompile well even C and C++ stuff for you (you can just use it as a C/C++ compiler dropin)
because of that one company has a contract with the Zig foundation to keep this well maintained for their Go dependencies
Funny comment!
Zig came too late, Rust and Go are both great and if you gotta deal with it, C is going nowhere.
@@leggysoft I was explicitly commenting at the cross-compilation situation here.
And guess what, Zig also brings its ease of cross-compilation to C and C++ (because it has that builtin).
after the citation of ousterhout I wen to look at the threads paper, and to me it seems ousterhout is still right, and pike got ousterhout's message wrong (just look at the conclusion slide), pike's own admission of "doing concurrency like things sometimes without even realizing it" is a problem and in agreement with ousterhout
(but then, of course, he later goes on to talk exactly about the problems ousterhout stated ...)
I want the wallpaper from the beginning!
Would be interested to hear more about introducing sum type (ie Rust style enum, or Haskell style data declarations). Especially around error handling using Option/Result sum types to handle nil/error values, along with some syntax to “bubble up” errors out of a function like Rust ? operator.
I die a little bit every time I see any non trivial go code, and > 50% of the line count is `if err != nil { return err }`
“But you should be explicitly handling errors!” Is the usual go community apology. Sure, if you actually handle them. If you’re just returning them for calling code to do something with them (probably just check for nil and return them again), that’s not “handling” them.
And having nil at all is just a massive footgun that could have been eliminated. Then go doubles down on nil by having typed nils, so there are a bunch of edge cases where nil != nil.
It’s like they heard nil was a billion dollar mistake, and said “You know what? Let’s aim for a TRILLION dollars!”
The interaction with interfaces is tricky. There is an open issue on sum types.
BTW rust/haskell Option is awful from composing and keep interfaces stable perspective. Most code keeps defensive stance and makes function arguments and results Optional to keep compatibility in case of requirement changes. You can't add or remove optionality later without code breaking especially for libraries. Zig at least allows to keep stability on T -> Optional argument refactoring.
@@doBobro I don't know any Zig, so if the argument T turns to Optional and receives "Nothing", will the function return error? Or simply panics? Maybe somehow Zig will pick a default value?
@@doBobro Oh, you are saying that all the call sites of the function don't have to change, so it's kind of like "Type *" (i.e. pointers) in C, but the function receiving an "Type *" has to deal with it probably being NULL?
@@doBobro But what about u64 -> Optional? Before, the caller just passes any u64, so the raw value of an Optional will be just that u64, than how can we distinguish Nothing and Something(value)? Will the Zig compiler automatically transform all u64 at the call sites into e.g. (true, u64_val)?
Great Talk
the overly strong dependence on git has been the bane of my existence
Honestly some of the go docs are still awful. Not as bad as a lot of the package documentation for a lot of packages like the AWS SDK for Go but that's not the Go teams fault
Thank you!
Seriously. Passed and amazing opportunity for o ask some “trivial” questions
I am shocked, what kind of audience was that? Bunch of students apparently with no exp. They can't even form a question for this man. Arenas was a good question, i would ask that since I think they are cool, but as he mentions, very dangerous if not done correctly.
26:54 Indeed, go's module system is it's one of the worst sides of it. It's way more better how node.js and rust handles that, when i struggle to understand go's module system i've experienced very big frustration.
** Strobe light warning **
(editor: some of us need this warning)
Go's biggest sin is being only moderately better than Java. It's no wonder C++ still plays a big role at Google, because Java already took over where C++ would have otherwise been used. The remaining cases where C++ is still used would not be written in Go for the same reasons it wouldn't be written in Java.
I do have to say that Go is quite a pleasant language to use when it comes to working with binary formats. Just the right amount of succinctness and type checking.
At the present moment (early 2024) Java is arguably in a better shape than Go. With the introduction of virtual threads in OpenJDK 21, there’s one less reason to adopt Go.
I’m saying this as someone who’s allergic to Java and who’s been rooting for Go for a long time. It might be a lost cause by this point unfortunately.
Java uses too much ram. Go is better. People hate java. People love go. Wtf are you talking about?
@@danvilela Go has a garbage collector -- which means it uses extra RAM just like Java does. Go introduced "goroutines", a threaded implementation of co-routines, but didn't solve the underlying problem of concurrency bugs. The only real benefit to Java users would have been the type system, but even there they didn't have generics until over 10 years later.
As such, despite the initial excitement around Go, interest has petered out. It was never going to replace C++ because of garbage collection, and it didn't do enough to replace Java. It's a quirky language with a moderate following, and that's all it will ever be.
@@chrimony
[speaking from web dev point of view]
In real world scenarios java memory usage is much higher than go.
In go you can really easy optimize memory usage, by using object pooling, which is not possible in java due to lack of out parameters (in libs / frameworks / std api).
In java most of the frameworks doesn't care about object allocation, and you end up with massive memory usage.
While I agree that java and go are simillar in the use cases, and java is more performant, in many ways, than go, the fact is that go ecosystem focuses on the performance, while java ecosystem focuses on the developer productivity (which leads to the configuration driven development) and often doesn't care about optimization, which leads to bloated software from the beginning.
Java ecosystem lead to the generation of the developers, which doesn't understand anything about web dev, they just know how to configure framework of the choice.
if err != nil go 🎊
Davis Maria Hernandez Helen Martinez Patricia
The existence of a design choice is the result of a lack of specification for the problem.
The thing is, "we are boring on purpose" gets really old after a decade. Now it looks more like an excuse for intellectual masturbation or just laziness..
I really don't think it has much to do with backwards compatibility either, a lot of cool things can be done while still maintaining backwards compatibility.
Theres been so much innovation in the languages world over the past decade. I'll even agree that most are bad ideas or not compatible with go but there are a few good ideas there and even some that a compatible with go.. if not copying, they should at least inspire some action or innovation..
What innovations?
@@AJewFR0 Just look at Swift. But to mention just one: optional parameters.
@@jabuciI find swift to be incredibly hard to read, with too many features. Anyways, optional parameters can be implemented with pointers and a bit of godocs on top of the function to make sure people know what the params serves.
I LOVE GO!
Baking telemetry into a programming language is a TOTAL NO GO. I would ditch the entire ecosystem and fallback onto ASM if all languages did that. Even those who assert that it is an opt-in should be scrutinized. Apparently they got paid by Ggl and speak on behalf of Ggl's interests.
STOP SPYING
STOP GLORYING BACKDOORS.
audience is so dead and clueless. god, there are so many questions, why making and working with dynamic libraries is so broken (still, 7? 8? years and counting), why not let people use the syntax that stdlib is using (for example creating a custom map type mymap[type]type that implements an rb-tree inside), what was the reasoning behind not allowing operator overloading and so on and so forth
Maybe you can clarify your question about dynamic libraries, I'm not sure what you mean.
As far as the map syntax, you can use myMap[type, type] since 1.18, which most people would consider just as good (I actually think they should allow map[keyType, valueType] with the built-in map implementation, but that's another discussion.)
I personally have never seen operator overloading used in a way that was clearer than named methods. Now to understand what >> does, for example, I need to figure out what types its operands are, then find the correct overload definition, when a well-named method just lets me read the LOC without digging into all of that. For a language whose design was largely driven by the principal of readability over tenseness, operator overloads seem to me like an illogical addition.
maps and slices are not stdlib features: they're part of the language itself. He mentions this during the talk as a bit of a wart, and something that might have been done differently if generics had been part of the original language design.
If it does ever happen, it'll probably be in the form of mapping some of that special language syntax to something a regular Go type can implement, and moving those container types to the stdlib.
We highly welcome you to come to the next GopherConAU. We also provide travel assistance to speakers, so if you would so incline, you could put in a talk when the CFP opens. CFPs have a 4% acceptance rate so it's pretty high.
@@natea.2926For things like linear algebra as an example, operator overloading makes things MUCH more readable IMHO. Especially if you're in a higher level language anyway. I think the problem is when operator overloading doesn't come with guarantees (for the most part) as seen in ie C++ or Python. But in Haskell, if you see a
@@gopherconau That snarky comment is so representful of the go community.
I don't think that the person mainly responsible for most of what Go got wrong is in position to objectively say what it got right and wrong
Silly take.
@@blain20_ Silly, but true
@@foljs5858 Nah. The designer of the language knows best what he should've and could've done.
You should look "retrospection" up in a dictionary.. This is a very healthy exercise and what you say is absolutely true, which is why one needs to be aware of it when making such an analysis. I find it quite incredible, that your only contribution to a 40+ min video, is your take without any nuance. Also, I mean you are incredible as in not-credible.
I just don't like the language named Go.
It's not even unique.
Go? Why is it called Go?
Is it because it's fast?
So unusual.
What a name! 😅
And languages named after snakes, rocks, random letters, corrosion and punctuation are better named?
Please add try catch
Hell no
Odin > Go 🔥🔥🔥
This adds nothing to the discussion.
@@gopherconau That's an arrow. From Odin to Go.
No disrespect to Go or Rob Pike, but try running the race condition checker on many popular Go projects. Ousterhout is still right.
@@linearz names withheld to protect the guilty
Could you elaborate on that? Why is that? Do you think that golang is more race-condition prone than other languages and why? Also, would that be a problem in all languages that implement stackful coroutines with green threads or is it specific to go?
@@Y-JA Ousterhout wrote that threads are--not always, but *usually*--a bad idea. Rob thinks he has refuted John's paper in some way with goroutines and channels. From what I have seen in popular projects, goroutines, channels, green threads, etc have only served to strengthen John's argument, not weaken it.
This is not specific to Go, but any "easy concurrency" language where people dash off threads without thinking carefully.
If Go had avoided accessing shared state from a different go routine, and forced all coordination via channels it would have gone a long way towards concurrent safety. As it is, you can do whatever thread-unsafe access to any data at anytime from anywhere, and you’re back in the same mess of having to hope mutexes and things are being used correctly (spoiler - they’re not being used correctly)
@@jasonstewart_kyYes, you can cause data races in Go, but the race detector is fast and easy to use in both unit tests and in e2e application tests. I do find races in my own code once in a while, but they are rare.