Earlier quoted context omitted.
Replacement for C in many areas it is used for != replacement for C in all areas it is used for
Sure, as long as Node, C#, Java, Haskell are all C replacements as well. Which I am okay with claiming, as GC has no considerable overhead for most use cases, but go is not unique in any way or shape.
Why I Don't Like Golang (2016)
221–230 of 237 posts
Re: Why I Don't Like Golang (2016)
#222Earlier quoted context omitted.
> If you need multi-pathed error handling (usually people don't and are just making it out of habit!), worry about what things can do, not what they are. When I'm looking at an error, it's typically for one of two reasons: 1. To set a correct status code, such as http 5xx (internal server error, our disk flaked) or a 4xx (user error, you gave us invalid input). 2. To provide a better error message, such as to localiz…
> To set a correct status code, such as http 5xx (internal server error, our disk flaked) or a 4xx (user error, you gave us invalid input). For this it's simple to wrap them at return site in something that offers `HTTPStatus() int` and check for implementing that interface , not any concrete types, in your handler. Also, those error paths should be dangerously hard to mix in the first place, you shouldn't be letting…
It's not though, the return site is inside the go stdlib. I cannot annotate it with new methods.
The only way to figure out how to translate all errors (whether to status codes or to other readable messages in localized languages) is to read the code and figure out what errors it might return.
> you want everyone to return wide error interfaces so you can categorize the entire universe of possible errors as you want. In the end this isn't a technical problem, it's an "I want everyone to cater for my use case" problem.
This is a technical problem. In Rust, libraries define error types and return "Result", which lets a library author decide what errors are interesting or not. If I think they have not classified an error that is useful for a caller, I can file an issue.
In java, exceptions have types, and I can know what types of checked exceptions a function might throw, and can similarly ask for more specific exceptions, or modify the library to provide them.
In go, _every_ library, due to go's error handling idioms and some mis-features of nils/type-inference, returns the most useless error type possible, the 'error' type, and I have to constantly read docs or code to figure out what types it might be.
I don't see how this isn't a technical issue with the language that, at the type-system level, it makes it an anti-pattern to return concretely typed errors in a way the type system can recognize them.
I don't agree with how you're characterizing what I'm saying as being "catering to my use-case".
Do you just never actually need to classify an error? Is it somehow weird to want to be able to provide a localized error to a user? Doesn't everyone have these problems too?
Re: Why I Don't Like Golang (2016)
#223Earlier quoted context omitted.
> To set a correct status code, such as http 5xx (internal server error, our disk flaked) or a 4xx (user error, you gave us invalid input). For this it's simple to wrap them at return site in something that offers `HTTPStatus() int` and check for implementing that interface , not any concrete types, in your handler. Also, those error paths should be dangerously hard to mix in the first place, you shouldn't be letting…
> For this it's simple to wrap them at return site in something that offers `HTTPStatus() int` and check for implementing that interface, not any concrete types, in your handler. It's not though, the return site is inside the go stdlib. I cannot annotate it with new methods. The only way to figure out how to translate all errors (whether to status codes or to other readable messages in localized languages) is to read…
type httpClientError struct { error }
func (err httpClientError) HTTPStatus() int { return 400 }
func (err httpClientError) Unwrap() error { return err.error } // if needed
It's not even anything special around `error`, Go's entire type scaffolding is built around doing stuff like this.> Do you just never actually need to classify an error?
Infrequently, and virtually never for errors types I didn't write myself (other than a tiny number of sentinels like UnexpectedEOF or DeadlineExceeded).
> Is it somehow weird to want to be able to provide a localized error to a user?
Yes, it's unusual for error details (rather than e.g. outcomes) to be localized for display directly to non-technical end users. This is also true of exception messages in Java. General-propose desktop client software is rarely written in either language.
I think you're too focused on the specific issue to see my general point about interface size.
Re: Why I Don't Like Golang (2016)
#224Earlier quoted context omitted.
> For this it's simple to wrap them at return site in something that offers `HTTPStatus() int` and check for implementing that interface, not any concrete types, in your handler. It's not though, the return site is inside the go stdlib. I cannot annotate it with new methods. The only way to figure out how to translate all errors (whether to status codes or to other readable messages in localized languages) is to read…
> It's not though, the return site is inside the go stdlib. I cannot annotate it with new methods. type httpClientError struct { error } func (err httpClientError) HTTPStatus() int { return 400 } func (err httpClientError) Unwrap() error { return err.error } // if needed It's not even anything special around `error`, Go's entire type scaffolding is built around doing stuff like this. > Do you just never actually need…
Even within your own program, you now have to read the code in "httputil" to understand what possible error types can be returned.
It's idiomatic to never return concrete error types, whether from the stdlib, or third party libraries, or even methods within your own program.
Even for types you do write yourself, you still have to either memorize what errors each method may return, or you have to constantly refer to docs or source code reading.
Clearly you think this is fine and go's type system is good enough for your use-cases, but every larger go program I've worked with, error handling has been painful since the errors are effectively untyped.
I assume we must have worked on different types of go projects if you haven't run into pain with this.
> Yes, it's unusual for error details (rather than e.g. outcomes) to be localized
I absolutely agree that it's outcomes which are localized, but to determine _outcomes_, you have to classify errors. If the _outcome_ is "File doesn't exist", that's a different error than "permission denied", so you need to classify. But the type you have is "error", so you have to constantly refer to docs.
Re: Why I Don't Like Golang (2016)
#225Earlier quoted context omitted.
> It's not though, the return site is inside the go stdlib. I cannot annotate it with new methods. type httpClientError struct { error } func (err httpClientError) HTTPStatus() int { return 400 } func (err httpClientError) Unwrap() error { return err.error } // if needed It's not even anything special around `error`, Go's entire type scaffolding is built around doing stuff like this. > Do you just never actually need…
You've constructed 'httpClientError', but how do you end up using it in your program? You have "pkg/httputil" or whatever, and the methods in it return "(Response, error)", not "(Response, httpClientError)". Even within your own program, you now have to read the code in "httputil" to understand what possible error types can be returned. It's idiomatic to never return concrete error types, whether from the stdlib, or…
Nonetheless, Go does provide ways to check whether an error either is or can do what you want, and ways to annotate errors with logic specific to your program. An `httpClientError` is an `error`. When you get an error from a source you want to treat as a 400, you wrap it and return it, as an `error`. You use `errors.As` on it as a concrete type, or an `interface { HTTPStatus() int }`, to use the method you've added.
Regarding localization, which is a significantly different problem - the outcome is e.g. "file can't be opened". It's hard to write good error messages based on the language's error messages but this is not a Go-specific problem at all. Either you constrain your operations to the point you can bound all your error types, or you don't and report the outcome + raw message instead of trying to localize causes. And yes, this is an unusual space to be using Go or Java.
Since you mentioned Rust, we could also consider how it solves the problem - `Write` returns a `Result` - `io::Error` has a (almost uselessly long and yet still) non-exhaustive `ErrorKind` - the last of which is `Other`, "used to construct your own Errors that do not match any ErrorKind." I.e. even in Rust's type system, they punted because otherwise you can't easily compose anything.
Re: Why I Don't Like Golang (2016)
#226Earlier quoted context omitted.
Naming a file is an obscure thing?
__main__.py? PRN? index.html? "This filename does something special" is hardly a situation unique to Go.
Re: Why I Don't Like Golang (2016)
#227Earlier quoted context omitted.
> Rust is guilty of this as well, mind you #[derive(Hash)] struct X{ ... } Seems easy enough to me? The only annoyance is if a third party type didn't implement Hash, but you can solve that with a manual implementation instead of a derive.
> you can solve that with a manual implementation instead of a derive. How? I thought the orphan rule said you can only define trait implantations at struct definition or trait definition
Re: Why I Don't Like Golang (2016)
#228Agreed with the article, though obviously it’s a bit dated (especially around generics and package management). My take is that Go is basically the new Java, with fewer abstractions and faster compilation. Although, the pre-Java 8 Java, before Java started to get a bit functional. Like Java it’s a practical, imperative, statically typed, garbage collected language with very good performance. Also like (pre-Java 8) Ja…
I would really like to see a benchmark on compilation speed. Sure, Go’s compiler is really fast by not doing any fancy optimizations - but.. have you seen javac’s byte code output? It barely does constant propagation, because it can get away with it due to JIT. So if anything, javac just starts up a bit slower, or the build tool does something at first start but otherwise java programs literally compile in a blink of…
Re: Why I Don't Like Golang (2016)
#229Earlier quoted context omitted.
I think most people in the industry pirated software when they were students or just beginning. But now that we make money it’s easier to just buy it. Friend of mine pirated photoshop when he was studying and after he finished and started his own business he started paying for it.
Photoshop being easy to pirate was a feature for Apple: the uptake was absolutely insane across all possible levels and eventually nobody uses anything else. Same with Microsoft in 90s: when students asked Bill what he's planning to do with the whole China copying it, he replied that let them get used to it and we'll find a way to charge later.
Re: Why I Don't Like Golang (2016)
#230Earlier quoted context omitted.
Sorry I meant to type $1000’s. Corrected it. I ran JetBrains software on one of those 1.5ghz MacBook 12” and it was totally fine. I don’t think it needs “powerful” hardware. Not like visual studio. Now that’s a pain!
> I don’t think it needs “powerful” hardware. That depends. If you have multiple large projects open at the same time, it'll eat a lot of RAM, even if it won't be too CPU intensive. I run it on a ThinkPad that has 32 GB of RAM, when I have about 6-7 instances of the IDE open and all of these services running locally (generally Java projects, the largest of which is around 4000+ source files), then it gets close to th…
Switching between Visual Studio is 15-20 seconds of wait time while it decides if any files have changed.