I understand duck typing of interfaces to types imposes some limitations, but it is by no means an absolute limitation. Given a set of Go source files, you can absolutely automatically find all types in those source files which match an interface. Sure, there could be implementations in other places as well, but the same is true for Java or C# or C++.
Also, note that the compiler already does this check whenever you try to use some type as a specific interface type, this is not dynamic binding at runtime.
I understand that, but it means I need to rely on tooling (which has limitations) to do something that is zero-effort in other languages, and that impedes easily understanding unfamiliar source code. It's not so much "Which types implement this interface", but rather "Which interfaces does this type implement".
For this reason, I'm not at all convinced that duck typing contributes to the fundamental need to write easily understandable and maintainable code. What does it add, or what problem is it trying to solve?
One commenter recently suggested putting, eg:
var _ MyInterface = MyType{}
at the top of the file to assert explicitly the interface implementation. This works but is a bit of a hack.
Duck typing is my main gripe about Go, but generally I like it very much, and find it very practical, especially (funnily enough given the article) it's tooling.
Oddly enough I've never needed to look up "what implements this interface" in Go. I've been writing Go professionally in a senior/team lead roll for over 4 years.
Usually I know what implements a given interface, as in the package I'm writing, I know what I've imported. Packages are usually small/narrow enough that there isn't ambiguity (i.e. I'm not reaching for some arbitrary implementation).
The only pain point that comes to mind is the bytes, io, and strings packages where there are many common interfaces and many implementors, but it's never really headache inducing.
The interface assertion you mention is useful for implementors to catch at compile time if they didn't implement a given interface (rather than find it at call sites), and catch where implementations break when an interface definition changes. You could put it in a test file, if you like, for the same effect.
> What does it add, or what problem is it trying to solve?
In Java, if you get a type from a library, and it doesn't implement a particular interface, you're stuck. You have to wrap it up in some intermediate type. It's useful to be able to use types that don't know about a particular interface even if they happen to conform to that interface.
However, I would agree that it would be useful to be able to specify which interfaces you intend a particular type to implement. (Or maybe Go allows this? I'm just talking about duck typing here, as I don't know Go very well.)
Also, note that the compiler already does this check whenever you try to use some type as a specific interface type, this is not dynamic binding at runtime.