In the context of Julia one has to point out that Python is slow. There is no sensible way around this fact. That you can mitigate the slowness of Python by using large libraries 99% written in C/C++ does not change this fact.
Yes a lot of Python developers can avoid the problem of Python’s slowness by relying on packages built in fast languages, however in a number of cases which matter to data scientists and machine learning this is frequently very difficult if not next to impossible.
Whenever you have a case where you need to be able to supply custom kernels to a library, Python will fall flat on its face. If you got a tight inner loop executed over millions of data points, and the code in that inner loop is Python, then you are asking for trouble. It is going to run slow.
One case you see this is with TensorFlow. You cannot perform automatic differentiation on custom Python code. Instead you will have to create custom nodes in C++, compile them and include them with TensorFlow. Then you can use Python later to orchestrate a bunch of C++ nodes to form an abstract syntax tree which can be automatically differentiated using the chain rule for derivation.
Sure people can labor through and get this to work. Just as people can write computer games in assembly code, if they have to. But is it desirable to do so? This is a real usability issue.
The reliance on a 2nd language do to the heavy lifting will in many cases cause a usability issue for Python developers. Let me take another example to illustrate this. In Julia I could create a large buffer of RGB triplets to represent an image and register image processing functions working on these types.
A Python developer will have to rely on something like NumPy which does not allow you to create large buffers of numbers represented as any type you like. They have to be a bunch of plain integers or floating point numbers. Python types are not allowed. Can you make it work? Sure. The same way a C programmer could optimize part of their program by writing it in assembly code.
Ideally you don’t want that. I remember a C developer writing video codecs I worked with years ago. He was an odd man out apparently for using plain C-code rather than any assembly. He would be in frequent contact with Intel to tell them when their C compiler did not produce optimal assembly code. The benefit for him working closely with intel was that he was able to keep all his code into a relatively high level language such as C, rather than having to maintain any assembly code.
This is a question of productivity. The work required to maintain a large C/C++ library for Python isn’t zero. If you look at the whole Python eco-system as developer hours spent maintaining both Python code and associated C/C++ code that adds up.
One of the advantages of Julia is avoiding this split. Instead of writing high performance packages in C/C++, you simply write them in Julia. It is a more productive language, and it allows the users of the package to contribute to it and not just specialists. How many Python developers are able to add a fix to something like NumPy or TensorFlow? My guess would be a small percentage.
I am not saying any of this makes Python a bad language. It is not about bashing Python. Unfortunately too many Python developers get all too defensive when dealing with criticism of Python. But the point is that if you are going to explain the advantage of a new technology, it is hard to explain that without pointing out the deficiencies of the current dominant technology that the new technology is trying to challenge or improve upon.
Nothing is perfect. Julia has longer startup time than Python because it uses a JIT. Let us be honest about shortcommings of different technologies. Some criticism is valid other is petty. That is Python is slow is fair to point out. To obsess about Python having significant whitespace is for the most part petty bikeshedding. On par with complaining about Julia having 1-based indexing as default.