My problem with Python, especially when reading someone else's code, or my own old bad code, is that I find that Python doesn't fit [my] brain.
The lack of typing (in my experience you always end up with a bunch of libraries that don't have type hints) means I spend most of my time just figuring out what I'm supposed to pass to a function (I hate the django docs. Give me something like docs.rs where I can quickly scan what functions something implements, and see what they accept and what they return instead of forcing me to read an 800 page novel that STILL doesn't give you that basic info), and writing tests and trying to guard against passing the wrong thing around.
It's gotten a lot better with type hints and typeshed, but I agree, not knowing what type an arg should be and hoping duck typing works out isn't great.
In my own code, I always use typehints and write good docstrings (nearly) everywhere.
Visual Studio Code's type checker saves so much time and has improved my code quality to no end. It is especially powerful on polymorphic inputs, making sure the different code paths operate on the input type you expect.
I started enforcing type hinting in my personal projects. 99% of the time it's easy and useful to add. When I can't figure out how to make a mypy error go away within 30 seconds, I just disable it for that line. I feel this makes for very good 80-20 value/effort tradeoff.
I will say that more than one bug has been found after I disabled the single line hint though! Always surprising to me how powerful types can be.
I do not see the benefit of type hints. Good docstrings (and naming of the function and arguments) are superior, at least for the human.
Type hints are too much clutter.
There’s a certain program size from which they start to make sense and further still the benefits are obvious - you have a computer to help solve puzzles for you, so why not use it if the puzzle is ‘will this peg fit into that hole?’ when you have thousands of pegs and holes.
And so you end up writing climb_the_wooden_ladder(l: WoodenLadder) plus climb_the_aluminium_ladder(l: AluminiumLadder) or press all into an OO hierarchy instead of
climb(thing):
'''Climb a thing with steps'''
# prevent run time crash:
if not hasattr(thing, 'getSteps'):
hitDeveloper()
Docstrings are great until you change your mind about something fundamental.
Once you make that big scary change you might have to rerun your unit tests dozens of times before you've found and fixed all of the bugs that your change caused.
A static type checker, plus a bit of foresight and diligence, will give you a much more complete view of the carnage up front, so that you have a good idea about the cost of making that change while it's still cheap to decide differently.
And the best part is that with python you can only bother with the type hints where you need them (e.g. at the boundaries between teams)
I agree with you there. The experience I was thinking of here involved taking a codebase which wasn't modular enough and making it modular. So the "big scary change" involved changes to the module boundaries (which are the only thing I bother with type hints for anyhow).
Since I'm programming in Python, I experienced invalid code only in very few cases, more or less just where the function expected an iterable and I gave a string instead of a list of strings (typing errors are well prevented by the colour hints e.g. neovim gives with the right plugin).
And some libraries sould be better documented.
But the compile time error messages of C or C++ or Delphi most of the time do not deliver a shorter feedback loop, because they are generally ugly and hard to understand.
And you should write tests in all languages, so static typing isn't a timesaver in that respect, too.
The lack of typing (in my experience you always end up with a bunch of libraries that don't have type hints) means I spend most of my time just figuring out what I'm supposed to pass to a function (I hate the django docs. Give me something like docs.rs where I can quickly scan what functions something implements, and see what they accept and what they return instead of forcing me to read an 800 page novel that STILL doesn't give you that basic info), and writing tests and trying to guard against passing the wrong thing around.