Maybe my understanding is idiosyncratic, but I see low coupling as most essentially meaning that the modules interact at small and well-defined boundaries, which gives you flexibility when you want to do things with the units like test them, replace them, etc.<p>Depending on an interface can be a kind of coupling, sure, but I think it depends. I think abstract interfaces, or at least statically typed data types, can be great for understandable systems...<p>In Haskell, there&#x27;s work being done on allowing some kind of module signature, so that you can have several implementations of the same API be compatible with the same source code. I&#x27;m interested to see how that will play out.<p>You could see a Java-style interface as a specific global name given to a set of method signatures. Using that name incurs a dependency on the library that defines it. Sometimes it makes sense to redefine the interface in your own library, and then you can use adapters to make other implementations compatible—but this is all kind of boilerplate stuff that you wouldn&#x27;t need if Java was more flexible with interfaces...