Typically large code bases have problems that are more intrinsic to organization than what language its in. Huge code cases in any language are usually fine if discipline is exercised.
And concurrency issues and memory overhead problem are from not knowing the right way to do it. Although I will concede that naive approach to both of those is sub-optimal.
> Although I will concede that naive approach to both of those is sub-optimal.
Paradoxically, this can actually lead to a better understanding of how to write performant code. When I first learned some of the be implementation details of python, I couldn't believe it was performant enough to work for anything ... after optimizing enough of it, I understand better what actually matters
Also people seem to forget the rule of premature optimization. Worry about performance when performance starts to be a problem. You identify the area with performance is lacking and optimize that. Compute is cheap, manpower is expensive.
> though it didn't when I wrote the 36kLOC program I had in mind).
Yeah, that was my assumption. Still, typing in Python feels very clunky compared to TypeScript. And even though it is much better after 3.8 and 3.9 updates, the adoption of typing in various useful libraries was relatively low as far as I remember.
> What problems are there with python variable scoping -- you can have global and local variables, shouldn't that be enough?
Maybe it is just me, but the scoping rules feel weird: blocks like "with"-statement or for-loops don't create scopes. There is no distinction between declaration and assignment. Sometimes you have to use those weird "nonlocal" and "global".
The scoping is bad, they should have copied Perl's "every block is a new scope" and added an explicit "let" keyword to define variables instead of overloading assignment. The "nonlocal" and "global" and stuff like "lambda x=x" is a big giveaway that their approach was wrong, but I guess it was too late to change it.
The typing has been great in my experience. Most of my deps have types and if they don't I can autogenerate them. The powerful typing of TypeScript is mostly not needed if you're not interacting with JS code.
Lack of typing support is a major advantage. If you don't have types you don't need interfaces, generics, etc. The resulting code is shorter and less bug prone.
You still need all of that. You just have to store that information in documentation and do analysis in your head instead of relying on a static analyzer.
Languages like Python and TypeScript support 'any' as a type, so you can always opt out of strong typing if you want. Most of the time generics are preferable to things randomly dying at runtime though.
Things don't die very often due to typing issues. The unit tests always pick up typing problems.
Testing the code's behavior implies testing the code's typing. And if you are not testing the code's behavior then the code isn't really tested at all.
Does your code check every single variable is not null before using it? That every function argument is of the expected type? That every attribute exists before it is accessed? And do you have unit tests for all of this too?
If so - then you're writing a whole lot of manual checking that a strongly typed language would perform for you, at compile time. If not - well then you're doing less testing than a strongly typed language would.
I agree that these issues are rare, and there is evidence that strongly typed languages have a similar number of bugs to dynamic ones. But suggesting that because you have unit tests, you don't need strong types, is a bit naive to me.
I don't actually care about any of that stuff. You are confusing technically wrong with not working. If the code works in production it doesn't matter that the code is technically wrong.
Testing via typing is very weak testing. Almost worthless. Type checking doesn't find many bugs in general.
Strongly typed languages have 2.5 times the number of bugs as dynamically typed languages per software feature.
Why would you intentationally add bugs to your code?
It doesn't make any sense to me.
Thinking using static typing in a scripting language is a good idea is pretty naive. It's like creating a version of Haskell with mutability.
And concurrency issues and memory overhead problem are from not knowing the right way to do it. Although I will concede that naive approach to both of those is sub-optimal.