|
|
|
|
|
by tptacek
8 days ago
|
|
Lack of typing is my biggest problem with Python, Ruby, and ES6 Javascript; I have to write everything twice, once to do the stuff I want, and once to double check that it's actually doing stuff, because a single typo blow the program up despite it parsing fine. Python typing is easy to dip in and out of. It handles None nicely; not as nicely as a true Optional, but enough for daily driving. The annotations are readable and simple. What more could I ask for, without asking for an entirely different language? Python typing catches a lot of bugs I'd otherwise have to tediously unit-test for. The only thing I don't like about it is that it feels like it relies a lot on importing stuff from the swamp of the Python stdlib. |
|
It does not, however, say anything about the actual productivity gain or loss of using types in a language like Python which does not require them — that should be the ultimate objective measure of whether they make sense or not.
With most languages, I get annoyed if I need to create separate types for every variant of a basic type (eg. let's have a firstNameString, familyNameString, CountryCodeString, CountryNameString... when is it too much?) - I do not think there is any way someone can prove going this deep improves maintainability long term. Eg. imagine you introduced validation of CountryCodeString based on ISO-3166, and there has been a change to ISO-3166 which happen every couple of years — how do you start supporting new codes? How do you deprecate and remove old ones? All of those are not helped with a type being very strict, you still have the persistent data to worry about, code actually supporting any of those, etc — the basic type check is trivial with a couple of small unit tests in comparison. You also quickly venture into a territory of complex types with complex interaction rules (this subvalue can be one of A if another one is X; but B if another is Y).
So for me covering the basic invariants with a unit test is not much more effort and — especially with Python — does not stop one from refactoring effectively and building stable, long-running systems.
Really, complex relationships in data are complex, and encoding it in a declarative way using a complex schema does not guarantee correctness (see Pydantic); if you want just very basic data conformance (type) checking, it's mostly a question of ergonomics.
Basically, you need to keep to some principles of code structure and architecture, but they are a simple set of principles — perhaps the fact that most Python projects do not abide by these should be a knock against Python? I only attribute it to the approachability of Python, but I am open to being wrong and this being the latent forced idiomatic use that projects always evolve into?