Problems I Have With Python
I've been using Python for about 10 years now. I love the language as much as I can any, and for the most part I enjoy writing in it -- and reading it.
However, despite its qualities it also shares quite a few massive flaws that slow me down and make me groan and sigh while attempting to solve problems in it. These are obvious flaws in design, in my opinion, that warrant re-looking at, but to which no real improvements are being made for some reason. (Incompetence? Politics? Both? Who knows.)
There are some languages (such as Coconut) which transpile to Python, but I argue that I should not have to build a better language on top of an already decent one.
Why can't Python accept some fairly sane changes and improve its experience throughout? Things other languages have and are well-received? Remove inconsistencies, and add useful features? Is that not what a growing languages aspires to -- or should?
With that in mind, here are some of the common issues I have with Python. Remember that it's a matter of opinion, although they stem from experience. Without further ado:
The standard interpreter bring rather slow; PyPy is nice, but its Python 3 support is very immature.
Parallelism is very bad on CPython and PyPy; threads are subject to the Global Interpreter Lock (GIL), and one must use
multiprocessing(which comes with its own bag of oddities) to get real parallelism.
asynciodoes not seem very well integrated, and does not seem as useful as libraries like
eventlet. They seem to have wanted to reinvent Twisted, but did so half-assed and did not include useful protocols (Twisted has line-based protocols, HTTP, etc. built in and easily subclassable.)
Quite a few legacy projects are written in Python 2, and it can take some work to port them. This is particularly a pain for libraries where I expect to
pip installthem and have them "Just Work".
There is an official tool
2to3which does not work in all cases.
The standard library is sometimes inconsistent For example, the
strtype has a
listdoes not. Even weirder,
listdoes not have
index(a related method).
Naming is sometimes inconsistent, despite Python 3's attempt at standardizing it.
Inadequate support for high-level functional programming
The BDFL himself, Guido van Rossum, has infamously declared that he does not like functional programming (odd, considering the language is built around FP concepts), and that
filtershould not be in the language. Well -- in my opinion that is a grave mistake, but more importantly the language suffers.
reduceis now tucked away inside the
functoolsmodule (as of Python 3), even though it is the only one of
filterthat is not replaceable by list/set/dict comprehensions! Yet
filterare still in the base global environment. What sense does that make?
itertoolsis useful, but duplicates quite a bit and does not include many useful functions standard in a lot of FP language standard libraries. It's also not too clear how some of them maybe use: I often find myself reimplementing
flatten = lambda xs: itertools.chain.from_iterable(*xs)(what a mouthful), as if I were supposed to figure this out on my own, instead of just providing a
For that matter -- flattening is something that should be so common that it were given a place in the global function set, but there is not even a way to do it in syntax.
Early in PEP 0448 was a proposed syntax for flattening in comprehensions:
>>> ranges = [range(i) for i in range(5)] >>> [*item for item in ranges] [0, 0, 1, 0, 1, 2, 0, 1, 2, 3]
This would have been very useful and allow flattening inline in comprehensions, but "this was met with a mix of strong concerns about readability and mild support." Sigh. (Nothing about that looks "unreadable" to me.)
The lack of tail call optimization in most implementations makes writing tail recursive algorithms rather pointless, unfortunately, even when they may be more legible than their iterative counterparts.
There is no standard way (even in
functools) to compose functions. There is partial application via
functools.partial, at least...
Lambda is awful
BDFL again stated that it was a mistake approving it, although again I disagree -- even in its abysmal state. Without it, I would not even use Python any longer.
Quite to the point, lambdas (anonymous closures) in Python are gimped. They are single-expression functions, which means no statements, even
nonlocalqualifiers. Prior to Python 3, this meant you couldn't even use
I imagine that attempts at making lambda not suck are met with "But that would require braces / funky indentation!" Well... what's worse, having a slightly goofy looking inline "def", or having a gimped language? Guido seems to add a lot of other dubious garbage, why not something useful? For the sake of some perceived "clarity"? Come on.
Inadequate data modelling facilities
Python classes are useful, but it is a ton of boilerplate to write variant classes such as:
class Node: pass class FooNode(Node): def __init__(self, x, y): self.x = x self.y = y class BarNode(Node): pass
Which is not even very useful, as there are no distinguishable
__repr__methods on it, no comparisons between them other than identity equality, etc.
Named tuples (
collections.namedtuple) would better solve this, but unfortunately they're immutable (like normal Python tuples) and thus make bad "bag of mutable data" objects.
Enums are also quite awful: your choices are using plain old strings or integers, or using the
enumlibrary which is not very widely used and has its own little quirks.
My propsal would be the addition of algebraic data types (aka "discriminated unions"), similar to how Coconut does it, and how many functional programming languages do it.
No, dicts with lambdas (see above) are not a replacement. No, long if-else chains are not a replacement. I want a nice way to match on data (preferably richly -- as with ADTs, ranges, ...) and associate matches with logic.
Please do not suggest awful hacks to do this, and fix your language instead.