The reason I liked it in Python is that it wouldn't flip a shit when trying to concatenate strings with various other things. And when using a strong-typed language, "forgot the type declaration" is usually the first stupid mistake I make.
This is one reason to perhaps learn a typed language before learning a non-typed language. Like learning to drive a manual before an automatic.
I sometimes accidentally write "for(int i=0; i< n; i++)" in Javascript because I'm so used to putting the type in, rather than your problem.
"The interpreter does everything for you" is both a blessing and a curse for learning to program.
C# has static typing and doesn't have a problem with adding things to strings.
"One" + 1 = "One1"
It's pretty easy to add that one to C++ too with overloads. It's better than complete duck typing because you know that anything is cast string if one of the things is cast to string, at compile time. "3" + 3 = "33" (or 3+"3" = "33") in all cases then. You can even overload the equality operator, so if you really want to compare strings and other variables for equality in the representations "if("33" == 33)" you can do that consistently. It will also tell you if there's no defined operator for a pair of types at compile time, so you don't need to run a program to work out whether it will fuck up.
For compile-time duck-typing, we have templates in C++. You just define a function or class which takes a type as a variable. Type "T" is the standard go-to, but the name can be anything. Then, the compiler works out whether the inputs make sense for you, and asks for clarification if they do not. You can in fact take any object, call it's "quack" function, and the compiler will work out whether there is a "quack" function for the thing you passed, spitting out an error if it's not a thing that "quacks". I'd prefer this to stupid run-time duck typing, which is defined as cross-your-fingers and run the program, relying on runtime errors to tell you that you made a mistake. What if the mistake was in a seldom-called branch of code? Compile-time checking would have prevented it ever being deployed with that error.