After many years of writing Python code, I just can’t stand the distraction and messiness that Types results in and the appearance of clutter and unnecessary characters and symbols to otherwise neat code.
After many years of writing and maintaining Python code, I respectfully disagree with your statement. The marginal reading overhead that type annotations bring (which can be alleviated by specific color schemes) dwarfs the ability to have a reasonable expectation of the code base trustworthiness.
PyCharm is really good when exploring Python. But this made browsing Python code on Github much more difficult. I've pulled down some project more than once just to get PyCharm's type inference and documentation. With type annotations it makes just reading the file without an IDE much nicer.
I'll never understand the desire to bolt types onto Python.
Dynamic typing is not a deficiency, it's a design choice. SICP for example, is filled with small examples of things you can do with dynamic languages you cannot trivially do with static one. There are certain styles of solving problems that suit dynamic languages particularly well, and anyone programming in a dynamic language should understand and embrace these.
There are of course drawbacks to dynamic typing, as is typically the case you exchange predictability for flexibility.
If, for your given problem or preferred style of programming, you want types there are so many fantastic languages around today that have much better type systems than what was available when Python was first gaining popularity.
Programming well in a statically typed language is fundamentally different than programming well in a dynamically typed language. Typing in python will never be powerful enough to allow you to "think in types", and if it were then python really wouldn't be python anymore.
Python is strongly typed though, in addition to being dynamically typed like you said. I think that makes Python a great language for type hints. I know the language won't do an unexpected conversion the way javascript would, yet variables aren't confined to just one type since it's dynamic - and the type hints don't hinder that at all. It's basically just an extra feature in Python for helping lint tools and as documentation for the user.
99+% of Python code is not intentionally using dynamic typing in order to take advantage of wacky SICP algorithms. It's good that Python allows that flexibility, but it's also good that in much more common cases you can indicate that a function argument should be a string rather than an int and have IDEs and linters be aware of that.
The usage of dynamic typing gets rid of a lot of boiler plate code and over complicated designs. Python code that doesn't use typing is generally better than Python code that does.
Would you please give an example of an algorithm or technique you think is particularly poorly suited (or impossible) in a statically typed language?
I’m curious to see how different an equivalent solution might look in a statically typed language and if any features like type classes or row polymorphism close that gap.
Yeah it’s just that Python dominates some ecosystems like machine learning. There isn’t much of a choice, so making these code based more maintainable is a valiant effort
I think the best way to get some perspective on unnecessary clutter versus valuable annotations is to wade into a project that you've never seen before, with many thousands of lines of python.
If you pick a line at random and try to understand what it does or why it's failing, you will have a hard time. Python (by design) is so mega ultra dynamic that each line could conceivably turn the world upside-down. Most code I've seen doesn't take advantage of that dynamism. But still - it's tricky just reasoning about stuff like: what kind of values that call could return?" or "what kind of an operation the index really does here?"
Funnily, I am about to accept a job to semantize some python code where nobody knows exactly what all those float, int, string and arrays in all those functions really correspond to.
I'm a python developer and within the last couple years I've encountered some interviews where they explicitly told me not to code in python.
Its because it's the language of choice for bad programmers who dont learn languages with any amount of depth. It's getting associated with mediocrity because it's so easy to pick up and low quality coders turn to it.
Your job solidifies this point. Literally, they need to hire someone to type annotate their code base because they don't know how? How low can you go?
Sure, and Java went through this phase too, and I'm sure so have plenty of other languages. It's the stage at which a language has reached mass adoption and it is inevitable, but it doesn't mean there's anything wrong with the language.
The problem they face is that they need to chain function calls, and spend ages discovering that a given function returns speed in m/s, whereas the next one expects miles/hour as an input. That is just a small example of the issue they face (that could solved by other means than statically typing the Python code), they really want to make things more robust.
This sounds like they had people working on that code before, who had no clear picture of making a consistent interface, even if only by convention. Basically one should always default to standard SI units, or let the type system guarantee it, or in lack of such a system write comments explaining things, such as units and perhaps even give variables appropriate names indicating the unit. Another option would be using libraries, which take care of calculating with units and checking the units given.
Hope you can fix it. However, be prepared for other kinds of issues, which arise when there was not much discipline in writing the code.
who had no clear picture of making a consistent interface, even if only by convention.
There are few conventions that are consistent across domains. As a concrete example I worked on a code base where functions from some libraries wanted angles as radians and the others wanted them as degrees. Both where internally consistent and followed all the relevant conventions for their domain, however when they intersected it was a pain.
Just to open up the discussion, I am looking at the FMI [1] standard as a way to describe the interface of different block codes. And then try to generate the FMI description from static analysis of the Python function definitions.
That’s my current plan of study. But as I said earlier, I have some background in static typing in Java, and I might find the current state of the art in Python not to be adapted to my idea.
Something that seemed common in Erlang, but less so in Python, was to annotate numbers using tuples. If you used both radians and degrees in a single code base, they’d be passed around as named tuples.
On the more serious side, what you're describing about python I feel happened to PHP long ago. I wonder if Ruby is next. Hope not. I'm doing mostly Ruby these days.
Neatness is in the eye of the beholder. Type safety is a quantitative metric of improvement. A program with type checking is more safe then one without.
A quantitative improvement cannot be argued against. A qualitative one... Well, personally I find types to be neater than no types.
Yes, though I'd say subjective vs. objective rather than qualitative vs. quantitative. Type safety is a quality, not a quantity (unless you're counting the expressions that type-check!).
Type safety is a quantity measured in type errors.
How many type errors in a language that is not type checked vs. how many errors in a program that is?
The numerical difference is quantitative. You can therefore do data analysis on this. Though a type safe program should in theory have ZERO type errors during runtime.
After many years of writing Python code, I absolutely love python types. We've got type checking in our pre-commit and in our CI, and they help our IDEs with completions. I don't think code with type hints in it really looks any different, it's still code.