Which many would prefer because it's implicit documentation. Never knowing what interfaces a go type implements sometimes bugged me. Functions, defined in interfaces often look different in style and paradigm so sometimes they stand out and made me wonder why they would implement such functionallity in this way, not knowing that the definition comes from a hidden interface. It also takes away the ability to quickly look up all die functionality because I would have to know the functions names and what interface they are defined in. Imagine a interface changes and you would have to find all the types you have to change.
This is exactly the problem you face in generic programming in C++ (and would have been fixed with concepts). You don't get to typecheck against the possible interfaces some object implements, and you have to be very good at parsing compiler diagnostics - assuming your compiler reports good enough diagnostics to let you figure out the problem.
I would gladly trade for the verboseness of making these relationships explicit if it let me typecheck and refactor with ease.
It is common to say "Foo implements the Fooer interface" in the doc on the function. Also, looking up what interfaces a type implements is 1.) impossible (depends on what other interfaces exist in the universe), 2.) pointless - you shouldn't care what interfaces it implements, you should look for functions that you want to use with your type.
You're also missing one of the best parts of implicit interfaces - you can use other people's types in your own functions with interfaces that didn't even exist when they wrote their type. To do that in languages with explicit interfaces, you have to write ugly wrapper classes around the other person's type for zero benefit.
Haskell typeclasses are an interesting way to achieve the same effect explicitly - if your module implements/returns/requires some type, then I can make your type "be" a member of my typeclass (pretty much equivalent of your class implementing my interface) without touching your module or creating a new type; the explicit declaration can be made afterwards to join together two modules that didn't know that the other existed but have types that are similar enough.
Ahh, that's cool, I didn't realize Rust could do that.
Though it does still require you to write the thing that tells the compiler their type implements your interface, right? Not a huge deal, but it's still essentially like writing a wrapper (though perhaps not as huge?)
Also, it sounds like you can't implement a third party trait on a third party type, so you can't use bill's cool log writer in joe's cool log roller.
> The point is speed is a false proxy for the quality of Node.js.
Well, no, speed is the actual measure of interest. The point is that reimplementations that change language also often change other design features, and that without knowing what else changed one cannot validate the attribution of the post-change speed improvement to Node.js.
To avoid problems like that, you probably want your dev environment as close as possible to your production environment. You probably also want to be testing your production specific code/logic (especially if you're not doing that on your local).