> What about the way Go handles errors today makes them not "strongly typed"?
Error as type or error as values ? the std lib promotes error as values (i.e. check equality) instead of errors as type (i.e. check the type). Go error system WAS written with errors as value in mind. There is no point having errors in place of exceptions if errors were intended to be used as types (which they are not, as said previoulsy). Basically developers are implementing their own mediocre exception system on top of Go errors.
The error as value thing made sense in C 30 years ago, it doesn't in a language created less than 10 years ago.
There are a lot of C inspired patterns in Go that make the language half modern/ half dated in strange ways. That's fine when one comes from C though, that isn't when one comes from anything remotely modern. But I guess it's why Go is successful, it's basically C with garbage collection.
I said that already. And that's not the problem at end. When you test an error, do you test against a value or a type in order to know what kind of error it is ?
> You can test the interface. A type is just an interface around memory, albeit more consrained.
Wow, again, that's not the problem here. Errors in the standard libraries are defined at values. There is no point testing it as interfaces, it will not give you the nature of the error, since they are all defined with fmt.Errorf . Do you understand now the problem ? the problem is being consistant across codebases between errors are values and errors as types.
That's because single error instances are much cheaper than always creating a new instance of a given type. No need to create garbage for lots of common errors. Of course you could have a dedicated type plus a singleton implementation of it in Go. But what would be the advantage? Checking if err.(type) == io.EofType does not give you more information the only checking if err == io.Eof, as long as you don't store any error instance related information in it. Which makes sense for custom errors and which Go absolutely allows you to do.
The compiler provides you no help at all with them, and no syntax that makes error conditions and handling separate. It also mixes application logic and recovery logic.
Basically everything that's problematic with returning a status int in C, but all new, hip, and backed up by Rob Pike's pseudointellectual bullshit and a bunch of Silicon Valley 20somethings.
They could at least, you know, have an Either type or something. Anything?
>It also mixes application logic and recovery logic.
When did this separation become law ? What if the "application logic" requires recovery ?
>They could at least, you know, have an Either type or something
(int64, error) in func ParseInt() (int64, error) is your Either type. And checking if you got the "left or the right side of the Either" is IMHO much shorter and clearer than in Scala.
It's not that it's a bad idea, just that because of the "nil interface" absurdity it can happen if you accidentally mix concretely typed variables and interfaces, as in the example.
This is perfectly valid and doesn't cause the nil issue:
return someErrorStruct{}
...where someErrorStruct is a strict that implements the "error" interface. Using structs for errors is fine, and is in fact generally preferable to singletons like io.EOF, which can (by their very nature) never be extended with more data about the error.
There's nothing absurd about it; interfaces are a reference type. If you have a reference to a reference, then checking the "outer" reference for nil doesn't tell you anything about the nullity of the "inner" reference. The advice is just a special case of "don't needlessly use pointers-to-pointers".
Go chose to rely heavily on nil pointers, which is a design mistake (see Tony Hoare's apology for inventing it). The resultant tension between interfaces and nils is, in my opinion, an absurd side effect that cannot be explained away as anything except an ugly wart. We should have something better than this in 2016.
I say this as someone who uses Go daily for my work and mostly likes it (despite the many warts).
Error as type or error as values ? the std lib promotes error as values (i.e. check equality) instead of errors as type (i.e. check the type). Go error system WAS written with errors as value in mind. There is no point having errors in place of exceptions if errors were intended to be used as types (which they are not, as said previoulsy). Basically developers are implementing their own mediocre exception system on top of Go errors.
The error as value thing made sense in C 30 years ago, it doesn't in a language created less than 10 years ago.
There are a lot of C inspired patterns in Go that make the language half modern/ half dated in strange ways. That's fine when one comes from C though, that isn't when one comes from anything remotely modern. But I guess it's why Go is successful, it's basically C with garbage collection.