Tuesday, January 7, 2020

Why don't I like python?

Some of you might have noticed that over the past 9 months I've been tweeting a bit under the hashtag #PythonSucks. As part of my pains with this language I asked the twitterverse to help me with finding sources that can confirm (or debuff) the claim I've been hearing a lot about python contributing to developers' productivity (for an example of this boast check this almost 5 y.o. podcast episode, around minute 11:30). During the conversation that sprung up from this question, Maaret mentioned it will be nice to see what am I missing when working with python.

As I went on to start answer, I figured out I have a bit more than a tweet's content to say about it - and so, this post is on. Some of the things I dislike about python are probably due to its nature as a dynamically typed language (I don't have a lot of experience in other languages that share this property, so I'm comparing it mainly against java and c# which are the closest statically typed languages (unlike c++ or c which are a bit more low-level)

So, what is it I don't like about python?

  • It's chaos prone.
    While it's definitely possible to write bad code in just about any language, my feeling is that in python writing well structured code is an extra chore. There are "type hints" that allow me to state "this variable should be of this type", but it is only optional, so we need to remind people to do this. It is possible to put multiple classes inside a "module", so we have to take care and ensure that the files are not growing out of proportion. The lack of the "private" concept is pushing people to abuse python features (check "name mangling") and instead a coding convention was invented to indicate "this should be private"  I also want to smear the variable scoping, but I'm not sure I understand it enough to do that.
    Under the mantle of "consenting adults" the language is allowing too much freedom and entrusting the programmer with the quite heavy task of keeping everything tidy with no purpose other than tidiness. Another example is the stupid decision in holy PEP8 (python coding style) with regards to string quotes (use single or double quote?): "Pick a rule and stick to it." Really? 
  • Tooling support sucks.
    Don't get me wrong here. I am rooting for my favorite python IDE (I use PyCharm) which saves me a lot of effort and is making everything less painful. Still, even with my limited use of the language, I found some stuff I was missing comparing with my favorite java IDE by the same vendor (IntelliJ) - since stuff is dynamically typed, auto-complete is weaker (type hinting helps, where it exists), the same property is probably why I spent several hours looking for a "generate equals and hashcode" functionality that was built-in in IntelliJ but missing from PyCharm - it is simply more difficult to do if there isn't a defined set of fields. Another thing that works less well is finding usage of a function, and I'm sure there's more. The tool vendors just have less metadata to work with
  • It's difficult to read.
    No, I'm not speaking only on the lack of curly brackets and reliance on indentation (there's a reason why whitespaces are ignored in most other languages - they are invisible!) I'm speaking on what seems to me like favoring writing code over reading it. It starts with the odd ternary operator ("a=c if bool else d" is done in  most other languages I could find as "a= bool? c:d" where we first inform the reader that this is a question) goes on with convenient to use but meaningless constructs such as for\while: ... else: (what does it mean to have an "else" statement on a loop? ) and goes on with removing the most useful metadata - types being send and returned. Sure, one can put type hints, or have this information in the docstring, but as we all know - documentation gets out of sync with the code very fast). So sure - I might have less lines to read per function, but I'll be forced to hop into all of the functions I'm calling just to see what am I getting from them.  Personally, I also don't like the convention of using less braces (my IDE yells at me if I write "if (a>b):" and would rather have me write "if a>b")
  • Libraries are difficult to use.
    Sure, another of pythonistas boasts that I've encountered is that python libraries have great documentation. While this might be true, I prefer not needing to read the documentation except for finding about corner cases or difficult to explain stuff. It's those missing types again. The only way know that the parameter "X" is supposed to be duck-typed as a string is to read something outside of the code (I have not encountered a library that used type-hinting, I assume they are some). There's a very popular way of sending parameters as "args, kwargs", which means that just to find the names of the possible parameters I'll have to step outside of the code.  
  • Importing a file executes it.
    I don't think I need to add here anything. 
  • Dependency management?
    This one is probably just something I need to learn, but I haven't found out yet a too to help me with dependency management (such as maven or Gradle in Java).
  • It's a special bloody snowflake.
    It might just be my feeling, but sometimes I can just stare at the code and wonder what have the designers of a specific language quirk been thinking (oh, who am I kidding, I'm always blaming that Guido chap). We've discussed above the ternary operator, there's the odd choice of not including a "switch\case" support in the language, having "join" as a method of String instead of a method of the collection, and a plethora of tiny things I encounter but cannot recall at the moment). It seems that python just wants to be different than other languages just because, and I prefer things that stick to the convention unless there's a reason not to. 
  • Say "pythonic" one more time...
    Seriously, are we professional coders or a part of a religious cult? While this can be used to improve code aesthetics  I've seen this argument used to justify ugly code ("It's more 'pythonic' that way ").  
Those are the pain points I think are most visible to me at the moment, and from the technical point of view, I  don't think adding more would help. 
There is, however, one other property I really don't like - It's too easy to learn. 
Normally, you could think that being easy to learn is a good thing, but what actually happens in python is that the learning curve is longer. Yes, it is less steep, but on java or c#, once you are able to write a small scale exercise you have already faced some OOP principles (in fact, since every variable has an explicit type, the new coder must have faced this concept), in python, stuff just work without trying. In some manner, python is suffering from the same problem as the testing profession - it is really easy to get started with limited professional capacity, so people just assume it's easy and don't invest the further effort required to be good at what they do. 
Another part of that is that you could write some bad code and it will work and will be enough for quite a while. It makes python a great tool for non-programmers (such as data scientists who just need their script to work while they focus on honing their data science skills. a lightweight scripting language with extensive libraries is exactly what they need), but for me it only means that once you'll find that you are missing those extra bits of information to manage your project properly, you'll have a lot more to rewrite.