Dynamic languages excel at fast initial development and "gimmicky" code (wildfire monkey patching, introspection, dynamic code generation etc.), and to get there you pay dearly. Practically all other properties suffer; stability, maintainability, performance, memory usage, ease of deployment, distribution and so on and so forth.
That doesn't mean that dynamic languages have no place, or applications developed using them are somehow generally inferior to those written in statically typed languages; choice of language is only one mosaic stone of many. But it is also a foundation stone, and dictates many constraints, both technical, and social.
If print() in Python includes a string and an int, I think the interpreter should be able to implicitly cast my int to string in order to make it all work. As it stands, I have to go back in and cast it myself, which kills productivity.
Any idea as to why implicit casts aren't more supported in strictly typed languages?
I'd prefer a warning on runtime than having to go back to the code.
That's the difference between weakly and strongly typed. If you take a strongly typed language, and add implicit casting, you get a weakly typed language.
How this is resolved (or if at all) depends a lot on the language. For example, in C++ it is straightforward to define implicit conversions (which can become confusing). In Python on the other hand, it is generally up to the receiver to call some kind of conversion function, like str(), which will use an object protocol (like __str__) on the instance. This is what print("foo", 1) does, or "foo %s" % 1.