&gt; For instance, thanks to the implicit satisfaction of interfaces, I find it one of the easiest mainstream imperative languages to still create a separation between IO and pure code, by wrapping all IO behind an interfaced object, one that I may not even have to create (i.e., Files already implement io.Reader and io.Writer, io.Reader &amp; io.Writer also already have several test implementations available in the stdlib and it&#x27;s easy to adapt them to a few more), which then allows me to write some really good testing code, almost as good as Haskell. (In fact, swapping in alternate implementations is probably easier than in Haskell.)<p>I&#x27;m confused. How does not having to write &quot;implements Reader, Writer&quot; (25 characters to type) have anything to do with purity and IO effects?<p>&gt; interfaces are actually half of generics<p>Interfaces aren&#x27;t generics at all. Java had interfaces and Object as a supertype before it had generics, and it still had zero support for generics.<p>I do agree with you that Go has maybe 50% of the use cases for generics covered, but not because it has interfaces. Those don&#x27;t count. It&#x27;s because it has maps and growable arrays built in.