> You've still not made clear what's special about errors that makes the concern about errors, not all types, more than theoretical.
The way errors are handled in golang, its possible to ignore them accidentally. This doesn't happen with other types because you don't keep constantly overwriting the same variable over and over (immutability is generally good, another thing that golang lacks), increasing the likelihood of ignoring an error.
E.g.
a, err := foo()
if err != nil { ... }
b, err := bar(a)
c, err := baz(b)
A linter will complain if b or c are unnused, but it cannot complain that err is unnused, because it is used and has been declared before. Whats worse something like this
a, err := foo()
if err != nil { return err }
b, errBar := bar(a)
if errBar != nil { return err } // oops
> The computer doesn't have a concept of errors either.
This is exactly the same reasoning that golang authors gave about why it doesn't have a notion of optional or non nullable pointers. To the computer, a pointer is a pointer. This isn't the way to think if we want to make reliable and readable programs. Computers don't have notions of methods or inheritance or even functions either, everything is a jmp of some sort.
The entire field of programming is to make it easier for humans to reason about code, OOP, functional programming, etc. Otherwise, we'd all be writing assembly or machine code.
Errors are special because they need to carry certain state about the program when an error happened (e.g. stack trace). golang errors are basically strings, which is why people invented frameworks to capture stack traces in golang errors. On the code bases I worked on, this building of the call stack is either done manually (by wrapping errors) or by concatenating strings, or by logging errors everywhere and capturing the stack at the log site. Quite horrible experience overall and just keeps polluting the code with boilerplate the makes it even less clear what's going on.
I've experienced the issues that come out of golang's overly simplistic design. The overly verbose code that is hard to see what its doing at first glance, the non-composability of errors, the mishandling of errors, etc.
Other than exceptions, languages like Rust have it much better than golang. You still get to have explicit error handling, but with much superior ergonomics that make them much more difficult to mishandle.