OTH I only came to realize that I actually like duck typing in some situations when I tried to add type hints to one of my Python projects (and then removed them again because the actually important types consisted almost entirely of sum types, and what's the point of static typing if anything is a variant anyway).

E.g. when Python is used as a 'scripting language' instead of a 'programming language' (like for writing small command line tools that mainly process text), static typing often just gets in the way. For bigger projects where static typing makes sense I would pick a different language. Because tbh, even with type hints Python is a lousy programming language (but a fine scripting language).

> Because tbh, even with type hints Python is a lousy programming language (but a fine scripting language).

I'd be interested in seeing you expand on this, explaining the ways you feel Python doesn't make the cut for programming language while doing so for scripting.

The reason I say this is because, intuitively, I've felt this way for quite some time but I am unable to properly articulate why, other than "I don't want all my type errors to show up at runtime only!"

Learn how to use the tools to prevent that last paragraph.

Note1: Type hints are hints for the reader. If you cleverly discovered that your function is handling any type of data, hint that!

Note2: From my experience, in Java, i have NEVER seen a function that consumes explicitely an Object. In Java, you always name things. Maybe with parametric polymorphism, to capture complex typing patterns.

Note 3: unfortunately, you cannot subclass String, to capture the semantic of its content.

> Java, i have NEVER seen a function that consumes explicitely an Object

So you did not see any Java code from before version 5 (in 2004) then, because the language did not have generics for the first several years it was popular. And of course many were stuck working with older versions of the language (or variants like mobile Java) without generics for many years after that.

Exactly, I have never seen such codes [*].

Probably because the adoption of the generics has been absolutely massive in the last 20 years. And I expect the same thing to eventually happen with Typescript and [typed] Python.

[*]: nor have I seen EJB1 or even EJB2. Spring just stormed them, in the last 20 years.

An example of a function in Java that consumes a parameter of type Object is System.out.println(Object o)

Many such cases.

Sounds to be more of a symptom of the types of programs and functions you have written, rather than something inherent about types or Python. I've never encountered the type of gerry-mangled scenario you have described no matter how throwaway the code is.

If you like dynamic types have you considered using protocols? They are used precisely to type duck typed code.