A programming language.

Some things I've learned

Accept interfaces, return structs
Let the consumer package define its requirements. This removes the coupling from the consumer package to the producer package, and adds the flexibility of swapping producers as long as they implement the consumer's set of methods. It simplifies testing as well. When creating a concrete type, the consumer might be interested to call more methods from that type. Returning an interface requires consumer to use type assertion, which defeats the purpose. Returning an interface might also be "preemptive interface": producer preemptively defining an interface before it's used. Interfaces are implicit in go and allows to abstract after the fact. Preemptive interface increases coupling (consumer now coupled to producer) and makes testing harder.