There exist static analysis tools for Python, but compile time checks tend to be diametrically opposed to the run-time binding philosophy that Python embraces. It\'s possibl
"the run-time binding philosophy that Python embraces... makes "use strict" behavior unnecessary [and] especially undesirable"
Pretty good summary. Thanks.
That is essentially it. Static analysis tools don't help Python enough to be worthwhile.
Edit
"I'm asking for us to introspect on why we don't need it and, relatedly, why Perl programmers think they do need it."
The reason why is precisely the reason you already gave. We don't need it because it doesn't help. Clearly, you don't like that answer, but there's not much more to be said. Compile-time or pre-compile time checking simply does not help.
However, since you took the time to asked the question again, I'll provide more evidence for the answer you already gave.
I write Java almost as much as I write Python. Java's static type checking does not prevent any logic problems; it doesn't facilitate meeting performance requirements; it doesn't help meet the use cases. It doesn't even reduce the volume of unit testing.
While static type checking does spot the occasional misuse of a method, you find this out just as quickly in Python. In Python you find it at unit test time because it won't run. Note: I'm not saying wrong types are found with lots of clever unit tests, I'm saying most wrong type issues are found through unhandled exceptions where the thing simply won't run far enough to get to test assertions.
The reason why is Pythonistas don't waste time on static checking is simple. We don't need it. It doesn't offer any value. It's a level of analysis that has no economic benefit. It doesn't make me any more able to solve the real problems that real people are having with their real data.
Look at the most popular SO Python questions that are language (not problem domain or library) related.
Is there any difference between "foo is None" and "foo == None"? -- ==
vs. is
. No static checking can help with this. Also, see Is there a difference between `==` and `is` in Python?
What does ** (double star) and * (star) do for parameters? -- *x
gives a list, **x
gives a dictionary. If you don't know this, your program dies immediately when you try to do something inappropriate for those types. "What if your program never does anything 'inappropriate'". Then your program works. 'nuff said.
How can I represent an 'Enum' in Python? -- this is a plea for some kind of limited-domain type. A class with class-level values pretty much does that job. "What if someone changes the assignment". Easy to build. Override __set__
to raise an exception. Yes static checking might spot this. No, it doesn't happen in practice that someone gets confused about an enum constant and a variable; and when they do, it's easy to spot at run time. "What if the logic never gets executed". Well, that's poor design and poor unit testing. Throwing a compiler error and putting in wrong logic that's never tested is no better than what happens in a dynamic language when it's never tested.
Generator Expressions vs. List Comprehension -- static checking doesn't help resolve this question.
Why does 1+++2 = 3? -- static checking wouldn't spot this. 1+++2 in C is perfectly legal in spite of all the compiler checking. It's not the same thing in Python as it is in C, but just as legal. And just as confusing.
List of lists changes reflected across sublists unexpectedly -- This is entirely conceptual. Static checking can't help solve this problem either. The Java equivalent would also compile and behave badly.