
All the things I hate about Python - wslh
https://medium.com/@natemurthy/all-the-things-i-hate-about-python-5c5ff5fda95e
======
lvh
This starts off with a misunderstanding of what "strongly typed" means. Python
is strongly, but dynamically typed.

Static typing means you know the type of something at compile time. Dynamic
typing means you don't. The upside to dynamic typing is that the compiler
doesn't have to prove much about your program; the downside is that it can't
really prove much of interest either. Strong vs weak typing is about how much
your language is willing to fudge types in order to make an operation succeed
without errors -- be it the intended result or not. Both static and strong
typing tend to make errors be more obvious sooner. Both dynamic and weak
typing tend to require less boilerplate to make your program do things.

Python doesn't know the types of things in advance (dynamically typed), but it
is very picky about which types are allowed to interact (strongly typed). Even
in cases where the answer is obvious, like str.join, you still have to make
everything strings: "".join([1, 2, 3]) will fail.

To demonstrate why these are orthogonal, consider the other cases.

Haskell is strongly and statically typed. A program that adds a string and a
number together will be rejected at compile time because the compiler can
prove it's invalid.

C is weakly and statically typed. A program that combines a string and a
number may be accepted by the compiler, who interprets the number as, I dunno,
a wchar_t or something. Another example of weak typing is how C allows (heck,
encourages) pointer arithmetic and untagged unions/structs.

JavaScript is weakly and dynamically typed. A program that adds a string and a
number together will, at runtime, convert the number to a string and then
concatenate the two.

~~~
tln
You're correct but this barely changes the authors points:

"It’s virtually impossible to statically analyze"

and

"In Python a good amount of errors are discovered at runtime"

~~~
lvh
The rest of the points are silly rehashes of arguments as old as Emacs v vim,
but sure, let's go there too. We've done empirical research to see if this
matters. Charitably, the results are "inconclusive"[0].

> The first glaring issue is that I have no guarantee that is_valid() returns
> a bool type.

You can name functions ridiculous, unhelpful and misleading things in any
language. The very fact that you know to expect a bool undermines the point:
clearly, despite not having static types, a human managed to make a pretty
reasonable assumption about what a piece of code was about to do. Just because
the compiler can check that is_valid returns a string doesn't mean that hat's
magically a useful thing to do.

> The fact that I cannot, in the absence of perfect test coverage, verify the
> syntactical correctness of someone’s code is a big red flag.

Syntax errors are caught by the compiler. Semantic errors aren't caught by the
best type systems. At best, type systems are a way to encode a bit of the
semantics so that the compiler can prove things about it.

> To improve static type checking in Python, developers made libraries like
> jedi, pytype, mypy, and toasted-marshmallow, but they are often not used in
> most projects because they do not belong to the standard toolchain

I can not imagine the author actually used jedi and believes this. That's...
not how jedi works. I also don't know what to do with the argument of "oh, you
have an optional static type system but people don't use it because it's
annoying, this is why we should use a mandatory static type system" other than
shrug.

I like types! I think there are great arguments for types. I like the idea of
being able to have a type system prove that certain bugs can't happen. This
adds nothing but FUD and no new insights.

[0]: [https://danluu.com/empirical-pl/](https://danluu.com/empirical-pl/)

------
w8rbt
I love Python, and use it often. It's huge in many industries due to the ease
in which people from various backgrounds can learn it. However, I agree whole
heartedly with the article. Python does not scale, performs poorly and is
unreliable at run time.

I think this is true for many second generation languages, not just Python.
Perl, Ruby and JavaScript are really no different. None of these languages
were designed to scale, be cloud oriented and perform close to C. Thus, many
developers complain of 'hitting the wall' and try other languages because
their tools were not intended nor designed to do these things.

I also think Go (and languages like it) which were designed to scale, use the
cloud, be safe and fast (performance close to C) are the solution and the
future. Here's a quote from Ian Lance Taylor, ___" Go was deliberately built
from the start to support large scale programs implemented by hundreds or
thousands of different programmers. Those kinds of programs are written at
Google, and Go was designed to be used to write programs at Google."_ __

More from Ian on this topic here -[https://www.quora.com/Will-the-Golang-code-
become-unmaintain...](https://www.quora.com/Will-the-Golang-code-become-
unmaintainable-for-large-code-bases)

------
di
> There is no short answer as to what is fully going on here, but simply put,
> Python modules are packaged either as a Wheel or an Egg

This is a false dichotomy -- there are actually many different ways to package
a Python module, including source distributions (sdists). These are just the
two most well-known types of _built distributions_.

> The numpy module is a wheel, i.e. it is a source distribution that depends
> on a handful of system libraries — gfortran, blas, lapack, atlas — to
> compile properly.

This is not correct, a wheel is specifically _not_ a source distribution, it
is a _built distribution_. The dependency on platform-level libraries has
nothing to do with what type of distribution it is.

NumPy publishes a lot of wheels for a given release
([https://pypi.org/project/numpy/#files](https://pypi.org/project/numpy/#files))
each of which is platform-specific, since they are pre-built (pre-compiled)
for a given platform.

In the event that a built distribution isn't available for your platform,
that's when pip falls back on the source distribution, which requires the
build step (hence the dependency on gcc or clang).

------
bbrunner
To me, the core points seem like table stakes knowledge that one should have
before jumping into development with ANY language, not just Python. Every
language is a tool that is good at some things and not good at others. Cue the
standard if all you have is a hammer, every problem looks like a nail.

A few core things:

The GIL problem is frustrating. I generally just try to avoid writing threaded
code and instead execute calls asynchronously or run parallel instances and
work with Celery or something similar. For web applications, this tends to
work well enough for me personally but this is definitely a valid issue.

Python2 vs Python3 is sort of a done deal at this point, in my opinion. I was
a big holdout on moving to 3 for a while but, for the past couple of years, I
haven't had more than 1 or 2 cases where I had _serious_ issues. I don't have
to deal with legacy codebases though.

On a larger note, I would say that this all points to the fact that it is easy
to do things the "wrong way" in Python. The accessibility of the language is
great, but it is not without its issues if you go in expecting it to be a
fenced-in playground with batteries included (to mix metaphors).

~~~
btashton
The "GIL" problem is so over exaggerated for most problems. A significant
amount of threaded code is IO bound and in most of those cases the GIL gets
out of the way. Checkout the cpython code around the calls to things like
select, poll, epoll. If you are needing to do high performance number
crunching across multiple cores, then yeah it's a little more work, but it's
gotten easier and easier to write some C libraries for that or leverage
something like numpy.

~~~
bbrunner
I would agree it's over-exaggerated. In my day to day work, the GIL has
rarely, if ever, been the performance bottleneck. It usually traces back to
something outside of Python (e.g. a slow DB query or a slow API call) or to
something that has been implemented in python in an inefficient way (e.g.
writing something O(n^2) when if you read your algos 101 book or even just
searched stack overflow you could find an O(n) solution).

I also think that the whole "drop down to C argument" is sometimes viewed as a
cop-out when criticizing python, but I personally believe that being
proficient at high-level and low-level languages, knowing their strengths and
weaknesses, and transitioning between them when it makes sense is stronger
than just using purely high OR low-level. It's sort of like having multiple
gears on a car: you need all of them, and they are all useful and most
opportune in different scenarios.

------
jack9
> However, Python does not have a real privacy model.

> This is unsettling if you’re coming from a Java or C/C++ world and are
> expecting access modifiers

It's unsettling to a lot of people, but so what? I still don't see a solid use
case for where member access (not "privacy") is a good idea. Python is one of
the only languages to get access modifiers right (convention), imo and I don't
even like Python.

You could implement some "privacy" with a lambda closure (which gets
increasingly complex), but that's one more technique that lambdas are ill-
suited for.

~~~
DonaldPShimoda
The author makes a lot of strong statements based on their opinions. I wrote a
bit about their dynamic/weak typing gaffe in another top-level comment.

> lambda closure

Just FYI (not intended to be mean or anything), in formal PL theory this
phrasing doesn't make sense. A closure is the pairing of an anonymous function
(a "lambda") with an environment. Python's "lambda" is really just a lambda
--- it is not a closure. This is revealed in the common pitfall where you try
to create a list comprehension using a lambda to generate interior values.

~~~
jack9
The idea is to create a lambda that's sole purpose is to act as a closure for
member access restriction. I'm not sure how that could be misinterpreted, but
here's your prize.

~~~
DonaldPShimoda
I guess my point was that you should have just said "closure" instead of
"lambda closure", since that phrasing doesn't make any sense in a formal
context. Lambdas and closures are different things entirely. I really wasn't
trying to be patronizing or anything; I was just trying to offer information
in case you found it interesting, but I guess I missed the mark there. My
apologies.

------
nmyk
> Python is viewed as a ubiquitous programming language; however, its design
> limits its potential as a reliable and high performance systems language.
> Unfortunately, not every developer is aware of its limitations.

Hammer is viewed as a ubiquitous [sic] tool; however, its design limits its
potential as a reliable and high performance drill. Unfortunately, not every
carpenter is aware of its limitations.

~~~
MiaoYu_Goh
"Ubiquitous" is spelled correctly. Why the "[sic]"?

~~~
JadeNB
> "Ubiquitous" is spelled correctly. Why the "[sic]"?

For what it's worth, '[sic]' doesn't necessarily mean "that was spelled
incorrectly", only, literally, "thus": i.e., "that's the way it was in the
original; don't blame me." As such, it can be used to indicate misspellings or
'misconceptualisations' ("I know that it's the wrong word, but it's the one
that was there"), as nmyk
([https://news.ycombinator.com/item?id=17484468](https://news.ycombinator.com/item?id=17484468))
indicates.

~~~
manicdee
To expand on this excellent description, when JadeNB claims that “sic”
literally mean “thus”, that is because “sic” is the Latin adverb meaning
“thus”. Some people think that “sic” an initialism for “spelling is correct”.

------
philipodonnell
> Ok, so “hate” is a strong word, but hopefully this click-baits enough folks
> into reading this article with a clearer, more rational and unbiased
> demeanor than what the title suggests.

Self-aware clickbait is the worst kind of clickbait.

~~~
tomtimtall
All clickbait is self-aware. People aren’t not doing it by accident.

~~~
coldtea
People can very well do it because they like fancy titles, or leaving things
unspecified, or puns, or whatever, and not to drive visitors to their website.

In fact, before the web, authors have long used fancy titles for articles that
you had to buy the magazine or newspaper to even read, so they had no
advertising-like value to attract unsuspecting readers.

------
lvh
The author complains about CPU-bound performance and then mentions PyPy but
claims it's ecosystem is barren enough that the point stands. This claim is
presented without evidence.

In practice it doesn't really show up: the cases where code is actually
CPython-specific usually imply all the work is being done in highly optimized
C bits. Hence, those programs, despite being run on CPython, aren't CPU-bound.

Finally: while this FUD is really pernicious because it used to be
hard/impossible to get scientific code like numpy to run on PyPy, that hasn't
been the case in a long time. Right now you can just pip install numpy and
it'll just work.

~~~
dnautics
It will bite you when you don't expect it. When i work, we had a dev write a
IO trace playback engine in Python to do some IO performance testing. We then
deployed it on various platforms and got very strange results - eventually I
noticed when TOPing the node, the CPU was pegged at 100%, so this wasted about
2 months time of about ~4 developers

~~~
lvh
What was the root cause?

~~~
dnautics
Wasn't worth taking the time to figure out, since none of us were expert level
in python and we only needed a one-off profiling tool. I rewrote it in Julia,
which killed the problem.

~~~
lvh
So you have no idea what it was but you’re certain it’s Python’s fault?!

~~~
dnautics
Given that it was about 150 lines of code and I did a fairly straightforward
rewrite in a performant language in about a day, and the performance was
acceptable, yes.

------
cowpig
The typing, encapsulation, and packaging issues are features of the language
which have benefits and tradeoffs. The author of the article seems to balk at
them because they aren't what he is used to. Re: typing in particular, gradual
typing is something that's slowly becoming viable, and I think it's great.

The python 2 vs 3 issue isn't really an issue if you're starting with the
language. There was a time where lots of big libraries were only supported by
python 2, but that's definitely not the case any more.

OTOH the build system is definitely a common pain point, and the GIL forces
you to use other services (e.g. redis + multiprocessing) to achieve horizontal
scaling which is unfortunate. And of course python's crappy performance is
something anyone looking at languages should be aware of.

------
bb88
I've used Java/C/C++/Ada/Perl/Go and most recently Python all professionally
in one aspect or another. I settled on Python.

So being a professional Python/Django coder, I was aware of all these issues.
And yet, those issues do not seem to stop the Python train from moving
forward.

A couple of issues to note in his article: Everything he says is true, but the
conclusions are mostly false.

1\. Optimizing databases and data access are the number one scalability issue.
It's the hardest thing going from a monolith to a microservice architecture.
Goroutines, threads, etc. don't solve that for you.

2\. Threads are terrible in any language (except Erlang maybe), and reliable
code cannot be used with primitive thread constructs. Goroutines are good
enough, sure. Also python asyncio. But not threads. I've seen production
systems that no one could debug, because 3000 threads ran amok, thread
deadlocks, race conditions, etc. And you can't unit test threaded code
effectively either.

3\. All software has multiple build systems. C/C++ and autotools, CMake,
Scons, Waf. Java and Ant or Maven or Gradle or whatever. Go is sane for the
most part, until you get to dependency management -- goglide, govendor, etc.

4\. Strongly typed, statically typed systems (Java, C++) usually aren't.
Usually people rely upon that as a crutch to think they don't have to worry
about types, until they see NullPointerExceptions (java) or segfault (C/C++)
in production.

5\. Python code is only as reliable as the person who wrote it. But that's
true of C/Java/C++ etc. People have to understand where the pitfalls of a
language are, and that's usually documented in coding standards or style
guides.

------
pmoriarty
My main beef with python is its packaging management.

It's a clusterfuck of half-baked, non-standard, spaghetti code approaches.

The Zen of Python says _" There should be one-- and preferably only one
--obvious way to do it."_ Python package management makes that in to a joke.

~~~
ris
That's because package management is an extremely hard thing to do if you're
only trying to control one part of a system and have it work magically in
different environments. And so strangely enough programming language people
writing their own toy-town package managers get it wrong again and again and
again.

~~~
bb88
It's worth noting that autotools for building C/C++ was so broken that ESR
declared that SCONS (written in python) was a much better way to build C/C++
code.

------
jakelarkin
after 5-6 languages and coming back to Python I would say the worst things are

\- large and inconsistent stdlib api,

\- extremely wordy but somehow still vague documentation

\- overwrought build/packaging system (although tooling has improved)

\- endless runtime gotchya debugging in production

\- almost all the baggage of OO boilerplate but none of the benefits of type-
checking.

\- half-baked functional paradigms

~~~
breatheoften
Great list!! Captures my thoughts and complaints perfectly after coming back
to python following a few months in typescript land.

Although I would add the incredibly slow process start time to the list as
well.

------
mattlondon
Totally agree with this person's assessment on types.

I took over a smallish half-completed web application written in python a
couple of years ago. Nothing major - simple business-y analytics/data viewing
app with some fancy charts and tables etc - perhaps a couple of thousand lines
of code interfacing to backend database unique to our business. It had some
tests, but nowhere near 100% coverage. I needed to finish it off and then get
it into production.

Long-story short, trying to understand someone's half-completed python and
make changes to this was a HUGE nightmare for precisely the reason the article
outlines: python expects _you_ to remember _all_ the minutiae of all the code
you are calling. If you cant remember, then you need to suck it up and pick
your way through the code and mentally keep track of what is going on at every
stack frame.

So instead of thinking about the _actual problem_ you're trying to solve,
python forces you keep track of all the little bullshit that you shouldn't
need to care about. And even then, you cant be 100% sure you got it right
until you exercise that code (either through 100% test coverage, or - shudder
- at run-time at 3am on a Sunday when a user in Japan logs on).

So far from being productive and "easy to use", python for us was a nightmare
of low-productivity and frustration in only a very small application being
worked on by just 2 or 3 remote developers. I cant imagine the levels of pain
and suffering for larger projects & teams!

The "solution" is apparently extensive & specially crafted comments that
specifically explain the types used (that of course needs to be kept up to
date) - I find this fairly odious (why not just use a typed language if you
_need_ to put the types in the comments?!)

I know now that Python is looking at type hints as part of the language (PEP
484 -
[https://www.python.org/dev/peps/pep-0484/](https://www.python.org/dev/peps/pep-0484/))
that should help a lot.

Still, its not all bad. As a result of the pain of this application (which
incidentally was damn slow in production due to the processing we had to do on
the data in the python backend before we sent it to the browser), we decided
to learn golang and use that for future work instead and have not looked back.

Golang has the same feeling of fast-paced "throw things at the screen"
productivity, but is obviously typed (so you know about errors before your
users do) and orders of magnitude faster.

~~~
mistrial9
.. sorry to hear about the frustration, but almost all of these are ordinary
problems with application development. Maybe the original developer made a
mess, but that is ordinary too.. if you have a short-list of hmm .. ways to
solve typical problems, in a workflow you like, in a language and functions
you like.. then you can bring those to the new efforts.. production technical
engineering groups will sometimes just bid to remake the whole thing, using
their own ways, for exactly these reasons.. but individual developers rarely
have that option.. chin up!

------
dnautics
> there is no question that type safety matters for building and maintaining
> large-scale distributed systems in the enterprise.

Some of the largest-scale enterprise distributed systems, as in, at the
telecoms level, are written in erlang, which is dynamically typed, and highly
reliable.

~~~
DisownedWheat
Aren't Erlang variables immutable by default? I find that makes a huge
difference to the reliability of a program.

~~~
dnautics
If I had to choose between immutable and dynamic versus mutable and static, I
will pick immutable and dynamic.

------
natemurthy
Hi everyone, so I'm the guy who wrote this article. I'm sharing a video
recording of George Hotz writing some Python code. Note his reaction at 5:55

[https://www.youtube.com/watch?v=7Hlb8YX2-W8&t=355s](https://www.youtube.com/watch?v=7Hlb8YX2-W8&t=355s)

His outburst is an emotional manifestation of the different sources of
frustration I've had working with Python that I've tried to document.

A common theme I've seen in responses is that many claim that I've mistaken
Python as a weakly-typed language countering that it is indeed a strongly-
typed language -- obviously an argument of semantics. I'll define a "strongly-
typed" language as one where it is trivial to identify the type signature and
definition of any function or variable in a program. In Python, this is non-
trivial.

FYI, this article is also cross-posted on:

[https://news.ycombinator.com/item?id=16337435](https://news.ycombinator.com/item?id=16337435)

[https://news.ycombinator.com/item?id=16371338](https://news.ycombinator.com/item?id=16371338)

[https://news.ycombinator.com/item?id=16411765](https://news.ycombinator.com/item?id=16411765)

~~~
manicdee
I have exactly the same reaction to C#, C, Forth, Pascal, Prolog, etc:
regardless of the typing strength or compiler nitpickiness there will be
scenarios where stuff doesn’t go as planned because I didn’t understand the
problem domain sufficiently, and these errors serve to enhance my
understanding of the same.

Regardless of language, x -> a + 1 is not going to work if a never has a
value. In many cases handling “a doesn’t have a value” is the wrong way to
address the problem, because the problem should be solved as “figure out why
the data collection didn’t work, and propose a strategy for handling our
dataset when either a value is missing or is provably wrong.”

As an example one might assume that a video feed has exactly as many frames
per second as it says on the tin (eg: 24fps will have exactly 24 frames for
each second of video) but in reality there will be missing frames due to data
corruption, or even a mismatch in clock speeds meaning that over 100 seconds
you have 2398 frames instead of 2400. How do you handle the missing two
frames? The problem is there are no frames missing, it’s just that they were
never there to start with, and frame 1237 of another source has no direct
equivalent in the slightly-faster stream. You might alter the clock for
processing, duplicate one or two frames, use interpolated frames, or otherwise
process the various sources so that you get a consistent synthesised data
stream with which to do further processing.

Strong typing doesn’t help solve real problems.

------
amai
Python is the worst programming language, except for all the others I tried
(Fortran, C++, Java, Scala, Clojure, PHP, Ruby, Mathematica, IDL).

But seriously, the points raised by the author are valid. However despite this
Python is still a pleasure to use. In addition the author fails to mention
some newer things, which can help with some of the problems Python has:

1\. Python Type annotations
[https://docs.python.org/3/library/typing.html](https://docs.python.org/3/library/typing.html)

2\. Please use the concurrent futures package for multithreading:
[https://docs.python.org/3/library/concurrent.futures.html](https://docs.python.org/3/library/concurrent.futures.html)

3\. For distributed concurrency please use Dask:
[https://dask.pydata.org/](https://dask.pydata.org/)

4\. Please use pipenv for package management:
[https://docs.pipenv.org/](https://docs.pipenv.org/)

5\. For performance, have you tried numba: [https://devblogs.nvidia.com/seven-
things-numba/](https://devblogs.nvidia.com/seven-things-numba/)

~~~
ChrisRackauckas
Ugh the Numba claims. It still has a high function call overhead from Python
and is type restricted. I couldn't pass functions to SciPy ODE solvers without
a 10x overhead of doing things directly in Julia and C++, so while a ton
better than straight Python it was still bad.

Also there are very few packages actually using Numba. It seems that more
people like to talk about possibly using it than actually use it.

------
chombier
I am surprised nobody mentioned python's weird scoping rules for local
variables. It bit me countless times.

~~~
bb88
You mean:

    
    
      def myfunc():
        try: 
          while x in someiterator(): 
            a = x
            dosomethingwith(a)
        except:
          # Does a exist here or not?
    

If someiterator() raises then a won't exist in the function block. Otherwise
it will.

------
jimmahoney
I teach intro programming using python, and use it regularly for various
projects.

But I agree with the author's central point that the language has a number of
issues.

He mentions the python2 vs python3 issues, but doesn't discuss what is to me
the biggest problem of all that: there is no standard simple way to identify
within the code what version of python it needs or is written for. Coming
originally from the perl world, that has always seemed like a significant
oversight.

Nor does he mention several of my other biggest issues with the language, such
as the arbitrary assignment of some operations to global functions (i.e.
a=[3,2,1]; len(a)) while others are method calls (i.e. a.reverse()) which
return nothing. And then there's list(reversed(a)) and all the iterator
awkwardness ...

Explaining to students learning programming for the first time why neither of
these do what they expect is never fun.

    
    
        >>> print(a.reverse())
        >>> print(reversed(a))

~~~
singularity2001
Yes, much of what's wrong with python in one line of code: >>> reversed(a)
<listreverseiterator object at 0x7f1c3bf94310>

who needs a __str__ method for listreverseiterator anyways. they cherrypicked
the worst of the Java world: Unreadable names and batteries excluded. yuck!

------
thangngoc89
The thing I hate about Python related article: A big snake. It scares me every
single time. Please don't put a big snake in your articles

------
DonaldPShimoda
> Python is considered a weakly-typed or dynamically-typed programming
> language.

This isn't right. Weak/strong typing is on a different axis than
static/dynamic typing.

Python is strongly typed. There's no implicit conversion among types (which is
one marker of weak-typedness). For proof, consider:

    
    
      >>> 1 + '3'
      [...]
      TypeError: unsupported operand type(s) for +: 'int' and 'str'
    

_Strongly typed_ means that the types are protective, in a way. You put a
value in a box labeled X and that's it — you can only treat it as an X from
now on.

In a weakly-typed language, if your function expects an X and you give it a Y,
well, it'll do its best to make due.

Many people think that because Python is dynamically typed (i.e. you can pass
anything anywhere without compile-time restrictions), that it must also be
weakly typed. This is simply not the case. If I write a function which expects
an integer and I give it a string, I'm going to have a bad time despite the
fact that the code "compiles" and only fails at runtime.

\---

Edit: I've read further, and the author actually uses their lack of knowledge
on this subject to portray the Python community as being willfully misleading
in their promotion of the language:

> Python markets itself as a dynamically-typed programming language, similar
> to Perl, Ruby, or JavaScript. The word “dynamically typed” has a positive
> connotation, more so than “weakly typed.” Conversely, the word “strongly
> typed” sounds more positive than saying “statically typed.” Diction matters,
> because proponents of different camps will select a word-choice that
> reflects their bias of one programming language over another. Python is both
> weakly-typed and dynamically typed, which contrasts itself to languages like
> Java, Scala, C/C++, and Go which are strongly-, statically-typed.

C is statically typed, but it is also _weakly_ typed. You can treat any value
as any type if you so wish, either by explicitly casting or by removing checks
for implicit casts during compilation.

I'm going to finish reading this article, but... I don't think I respect this
author very much, based on what I've seen so far.

\---

Edit 2: While the author's points would be valid by themselves (GIL, build
toolchain, dynamic typing), the over-abundance of negative rhetoric shows that
the author was merely interested in writing a smear article of Python,
essentially. I think it's a pretty weak article overall, and would have been
aided by a more fair comparison with notes about _why_ some of these design
decisions were made (or at least a less-slanted writing style).

~~~
s3m4j
It's also in the Wikipedia page about python that it is _not_ a "weakly typed"
language. It's literally in the resume box in the corner : "Typing discipline
: Duck, dynamic, strong".

Edit: I was going to mention the author's confusion, but OP did it in their
edit.

Edit 2: The author is "Staff Software Engineer at Tesla" ? And he doesn't know
C pointers ?

~~~
DonaldPShimoda
It's worse than I thought. If you see my edit, I found that the author used
their complete ignorance of the (strong/weak)/(static/dynamic) distinction to
invent a claim of willful misdirection on the part of the Python community.
Not only did they not do their homework on the topic, but they tried to
portray people in a negative light to further their narrative. I find that
incredibly dishonest.

------
arwhatever
It aggravates me the abundance of scientific/mathematical packages that exist
for Python, because of all of the language shortcomings that this article
details.

No doubt your typical Math Ph.D. type doesn't want a language with a step
learning curve to implement their expertise, so what to do?

Perhaps everyone could at least switch to Go,a language which (as I
understand) provides for some basic static type safety, good performance, etc.

I spent six months working in Python a while back and I'll be intent to avoid
it from now on.

------
didymospl
One thing not mentioned by anyone yet, that kinda annoys me is the fact that
Python libraries use different naming conventions. Even though PEP 8 has
existed for 17 years now, there are many examples where I see
lower_case_with_underscores mixed with lowercase and camelCase in the function
names.

I know that many libraries and Python standard lib itself predate this PEP but
I don't understand why Python 3, which broke backward compatibility anyways,
did not fix that at least in the standard library.

~~~
yxhuvud
Oh yes! Or at the very least created aliases with the correct casing.

------
Grue3
1\. Significant whitespace.

If I had a dollar for every time a bug was introduced in Python code due to
incorrect indentation during code refactoring, I would retire already.

~~~
akx
Then you're not using an editor/IDE which is smart enough to refactor things
for you.

------
ethbro
All points are at least semi-valid concerns.

However, what is the cost of addressing them? Slower development (core lang
and ecosystem). Less use in niche fields. Less flexibility to adapt to new
challenges.

Python is a rusty toolbox that's been put together over 27 years.

You know why it's still around? Because people can use it to do the things
they want to do.

Fixing all the warts would give us the language we need now... in about 15
years. Which would by then be useless.

------
gkya
My take:

\- The indentation based syntax: it can easily trip you up when moving big
blocks of code around. You want to put this if else block somehwere else, hope
you get a syntax error, because you can get sth. that seemingly works but does
not do what it's supposed to do. Also sometimes finding where you are can be
difficult.

\- Dogmaticism: a big thing in the community. They'll wait 20+ years until
they add string interpolation, a feature common in many similar languages.
They'll wait 20+ years until they start to realise having expression
equivalents of statements is useful.

\- Breaking syntax: new syntax is added in what seems to be minor releases, so
you either avoid new syntax to be compatible w/ all the 3.* interpreters, or
you need to expressly avoid certain interpreter versions. And there's no
equivalent of Perl's "use v5.something;" so you need to write code juggling
multiple supported versions.

Still I think it is a nice language to have in your toolbox for the vastness
of the stdlib and the available 3rd party packages.

------
alanfranzoni
Oh yes, python packaging sucks. That may not be well understood. But the
languages that handle distribution very well are just a few, that i know of
(jvm based, .net based, go, possibly js with all the tools that exist) and
there'll be some that i don't know. But for most languages, distribution of a
software with dependencies is a great pain.

------
vpribish
lazy article. dude wishes python was java. also, it fails the snake-test:
python is named for Monty Python's Flying Circus, not the snake. anyone who
uses the snake is not clueful.

~~~
krylon
Well, to be fair, Python's logo resembles a snake more closely than John
Cleese.

------
Dowwie
Hate those things all you'd like, but that won't stop you or others from using
it and doing so regularly. None of these points are show stoppers for many
scenarios. That's good enough. Python is the best second language for
everything and first language at many things.

