| > you end up having to frequently write type-switches which are checked at runtime to do any sort of generic code. This baffles me. I think I basically never use any type-switches, with the exception of interfaces being used as a sum-type - in which case the problems you mention with type-switches just don't come up. > Case in point: to do something as painfully simple as reading a file, you need to import bufio, io, io/util, and os. I don't know what you mean here. `ioutil.ReadFile` reads the whole file, done. Even if you prefer linewise-scanning, you still only need `bufio` and `os`. But even if you'd need all those packages to read a file: So what? Like, I honestly don't understand what's the problem with that. |
Here's how to read a whole file then loop over the lines:
Here's how to stream a file one line at a time: Here's how I, at least, would like it to work: The critical point is that I don't want to care whether `file` is a byte slice or a byte buffer, and Go doesn't let me not care. I want to be able to write code that deals with "enumerable data of some sort", once, and then works no matter how the caller decides to provide that data.Go (intentionally) makes it exceedingly difficult to obscure how a piece of code works from the rest of the codebase, and I personally think that's a fatally poor design decision. In my experience, it makes it difficult to decouple modules since code often has to be at least somewhat aware of quite a few implementation details of a library in order to use it correctly. It makes it really difficult to build higher level abstractions that don't leak. I have a much harder time in Go getting away from thinking in `int`s and `floats` and staying terms of the domain objects that I actually do care about.
"How" a piece of code functions is at best the third, and probably only the fourth most important question (behind "why", "what", and probably "when" if you use any concurrency at all), but Go forces it to be front and center at all times.