Not many downsides, if implemented right. Problem is, most languages have very simplistic type systems, which get in your way, specially if you are trying to code a function that will operate with many different possible &quot;types&quot;.<p>Then they add kludges to make life bearable (see also: Generics), that will then add complexity. And are sometimes horribly implemented (see: Java&#x27;s type erasure), or C++ compiler authors struggling with its template system (and users struggling to this day).<p>Or sometimes they don&#x27;t even add the kludges, making life tedious (see: Go, and endless discussions about adding generics to it)<p>The other category of hacks is what&#x27;s usually called &quot;Reflection&quot;, or &quot;Introspection&quot;. Any time a language designer feels necessary to add such a name for the ability to lookup things, then you know you are in a world of pain. The contortions required to by some languages to implement Ruby&#x27;s &#x27;respond_to?&#x27; method can get ridiculous. So much so, that the usual workaround is to add &#x27;interfaces&#x27;, which are a type(that does nothing useful), and so you can check the type. Or pass it around to something that will expect that over-arching type.<p>Sometimes you just don&#x27;t care about a thing&#x27;s type. And, many times, the types that you should care about are not the ones that are actually specified. If I&#x27;m doing something important, I don&#x27;t want the compiler to check if the type is integer, I want it to check if the type is, say, Miles, as opposed to Kilometers. That&#x27;s what&#x27;s important, or my costly space probe will literally crash.<p>A language should make it easy to do so, otherwise people won&#x27;t bother. Or probes will crash. Even though the program compiled. And the UML diagrams are spotless, with the factories all building the object types they were supposed to.