Great article! I'd added one can program in Python with speed of thought (can't find who told this, it was a couple of decades ago). I believed in Python right after I discovered it circa 1998 - version 1.5.2. it was almost nowhere back then, but language designed valued developers ergonomics and it paid off as a popularity of the language now.
Of course, C, C++ (and now Rust) and even Assembly will always be needed, and in my opinion it's beneficial for serious programmers to learn them even before Python to understand how computers work.
As for Java, I think the language is not to be programmed manually. It is probably best to be used with some code-generation tools with source code in some higher level "programming language" (or UML diagrams). I've never done anything serious in Java though, but with small projects it seems that Java requires heavy IDE support for the speed of coding usual for Python.
Also Ruby has not been mentioned. I've never studied Ruby because it's in a sense in the same niche as Python. My only grievance with Python is that Elixir is based on Ruby syntax (and Ruby syntax has more punctuation, and those who like punctuation can go all the way to Perl).
Dynamic typing, as you said, is not a problem in itself. Unless you are using some theorem proof assistant language (Coq, Agda, Idris2, ...) with dependent types and other cool constructs, type-checking can be performed with code analysis tools just fine.
One more point for dynamic typing is (I am still searching for more proofs of this than just words from Uncle Bob praising Clojure and LISP as ultimate programming languages), rephrased with my understanding:
- static typing does not help with dynamic runtime constructs [think JSON schema checking for dynamic JSON schemas because JSON is just one type, and JSON schema can be defined at runtime]. This means, that with dynamic typing rich user-land typechecking is still needed so compile time check (static typechecking gets you only so far: "yes, this is JSON, but insides cant be checked at compile time" - and it's inside of the JSON, which is the main concern and source of type errors!). This insight was very valuable for me to realise that "dumb" static type checking is many times not as useful as it is advertised and can force programmers to develop their our typing subsystems to handle dynamically typed data structures.
Here I come to what I miss from Python:
- multiline lambdas (or blocks)
- pattern matching found in other functional programming languages like Haskell or *MLs