3 ms·
I don’t get the “abusive relationship” metaphor. It just seems like the “abuse” metaphor is an attempt to stir up emotions. Every language has its own weird wa
by klodolph 5y ago
I don’t get the “abusive relationship” metaphor. It just seems like the “abuse” metaphor is an attempt to stir up emotions.
Every language has its own weird way of doing things. You decided Go wouldn’t work for you? Ok, I get it. People who stick with Go are in an “abusive relationship”? Seems like an attempt to stir up a flame war more than anything else.
I’ve never encountered a language that I’m 100% happy with. It’s always been about cataloguing the tradeoffs. I’ve even designed my own domain-specific languages a few times—languages that are laser-focused on solving a small set of problems that I have. It seemed impossible to design a language that would even solve my narrow set of problems in an ideal way. I was always making tradeoffs, from the syntax to the semantics. I’d make syntax for one thing slightly simpler, and then I’d realize that I introduced some ambiguity, so I can make the parser way more complicated, or I can make the grammar way more complicated, or maybe I try again. Over and over again, “simple” changes in small languages turned out to be diabolically complicated.
There are plenty of languages that I’ve personally just stopped working with because I can’t deal, personally, with the design decisions. Java is one. Haskell is one. (And the reason I gave up Haskell is all about finalizers, FFI, and the library ecosystem, it’s not about types or the language itself.) Rust is another, but I check in every once in a while to see if Rust has improved. I’d love to give up on C and C++, but realistically, there are too many existing libraries that I want to work with, and it’s often more fuss working with FFI than to just write C++ in the first place.
And just to speak about Go… there’s a small hobby community I’m in. People build their own tools to get things done. There are tools written in Go, and there are people who complain that the tools are written in Go. They think Go is awful, they hate it. But the complainers (in this particular community) don’t seem to be writing any tools themselves. Instead, we keep getting new tools, written in Go.
The history of language design is the history of people making decisions about how to design their language, and then discovering that the decision had unintended consequences, like, five or ten years later.
- mcculley 5y agoIt sounds like you enjoy Go. That is great. I am referring to TFA/post which sounds similar to many experiences with Go. Of course all languages have pros and cons. I am referring to the specific situation where people are expecting a modern language and ecosystem heavily influenced by its user community. Go is not such a language. People should have different expectations. > The history of language design is the history of people making decisions about how to design their language, and then discovering that the decision had unintended consequences, like, five or ten years later. I agree completely, which is why it is so surprising that people adopted Go when it seemed to learn very little from history.
- klodolph 5y ago> I am referring to TFA/post which sounds similar to many experiences with Go. Lots of people have bad experiences with Java, C++, Rust, Python, or JavaScript. I've had bad experiences with all of those languages, as well as bad experiences with Go. I don't think you've managed to articulate what makes Go different. I'm not saying you should use Go. I will say this: it sounds like you have opinions about Go, and I can't tell if you're trying to imply that those opinions are somehow universal or common, or reflect some actual design flaw in Go that you can articulate. "Many are not happy" about Go generics but that's inevitable, IMO. I don't think there's any possible language design decision that won't make many people unhappy. You might as well be asking for pizza toppings that make everyone happy. > I agree completely, which is why it is so surprising that people adopted Go when it seemed to learn very little from history. I can understand why you would think that way, but Go seems to me completely different. When I look at Go, I see a ton of small decisions where it seems like (to me) that the Go language designers have taken some fairly sophisticated lessons from history. Things like: - Error handling, - Strings, - Default garbage collector tuning, - Generics, - Dependencies, - Versioning. Just to pick an example... Java's checked exceptions are a good idea, but have some unfortunate consequences when Java is used for larger projects. One of the key problems is that when you handle an error, you don't just need to know what the error is, but where the error came from. Some errors can be handled at a distance and some errors must be handled near their origin. Errors in this second category can be made into checked exceptions in Java--at least, that's the idea--but in practice, it's a bit of a mess. If you pull back from dividing errors into checked / unchecked variants, then you lose the ability for the language to help you distinguish between errors that can be handled locally and errors that can be handled at a distance. IMO, Go's decision to use error returns makes the decision that "local error handling is default", which is a pretty nuanced take on things that I really appreciate. I don't think anyone would have come up with Go's error handling approach without the lessons from Java's error handling approach. Some people hate it. That doesn't mean that it "didn't learn from history".
- samhw 5y agoThis is an extreme intellectualisation of Go's error handling, which is literally just "errors are nullable strings returned by functions, and you have to check for them"[0]. I can't see where Go has learned from anything in PL research or practice, and indeed it's famous for not having learned: errors can't be matched; any hacky matching solution is unhelped by the type system; nor does the type system enforce checking for an error before accessing a value; adding context to errors is an absolute clusterfuck (in the absence of anything that could be called a type system) and therefore you end up with a load of "failed: op failed: encountered error: service could not load foo: error: database error: EAGAIN". I just can't make sense of your argument. You say Go has learned some lesson from Java's checked exceptions, because ... errors are return values. What does that have to do with checked exceptions? Do you mean to contrast it with exceptions themselves? It certainly seems a complete non sequitur in relation to the (type) checking of exceptions. If your point is the "exceptions vs values" argument, then that's certainly one that's been hashed out at length, but I fail to see how picking one approach - of the two only approaches that any language can pick, both of which countless languages have used - is evidence of some kind of deep thought and originality.