Because Python has NumPy, which implements vectorized math on arrays and matrices. Machine learning algorithms are implemented naturally and efficiently with those primitives. PyTorch, TensorFlow, and I think every other machine learning framework in Python all use NumPy.<p>JavaScript, Ruby, and Perl either don't have this abstraction at all, or they have much weaker versions of it, and many fewer scientific libraries.<p>NumPy started in the early 2000's and continues to this day. It takes decades to build up this infrastructure! This recent interview with NumPy creator Travis Oliphant is great:<p><a href="https://www.youtube.com/watch?v=gFEE3w7F0ww" rel="nofollow">https://www.youtube.com/watch?v=gFEE3w7F0ww</a><p>He talks about how there were competing abstractions like "Numeric" and another library, and his goal with NumPy was to unify them. And how there are still some open design issues / regrets.<p>There were multiple people in the nascent Python community who were tired of MATLAB, not just because it's proprietary, but because it's a weak and inefficient language for anything other than its scientific use cases. You won't have a good time trying to write a web app wrapper in MATLAB, for example.<p>The much more recent Julia language is also inspired positively and negatively by MATLAB, and is very suitable for machine learning, though it doesn't have the decades of libraries that Python has.<p>-----<p>The NumPy extension was in turn enabled by operator overloading in Python (which is actually a very C++ influenced mechanism). JavaScript doesn't have operator overloading; I'm pretty sure Perl doesn't, but not sure about Ruby. Lua and Tcl do not have it. (Lua does have a machine learning framework though -- <a href="http://torch.ch/" rel="nofollow">http://torch.ch/</a> -- but I think PyTorch is more popular now.)<p>So if Guido didn't design Python with operator overloading, then NumPy would not have grown out of it.<p>Also relevant is Guy Steele's famous talk <i>Growing a Language</i> (late 90's or early 2000's I think). He advocates for operator overloading in Java so end users can evolve language with their domain expertise! Well Java never got it, and Python ended up having the capabilities to grow linear algebra.<p>Guido has even said he doesn't really use or even "get" NumPy! So it turns out that an extensible design does have the benefits that Steele suggested (although it's a very difficult language design problem.) There have been several enhancements to Python driven by the NumPy community, like slicing syntax and semantics and the @ matrix multiplication operator. And I think many parts of the C API like buffers.<p>-----<p>Another interesting thing from Oliphant's interview is that he really liked that Python has complex numbers. (I don't think any of JavaScript, Ruby, Perl, or Lua have them in the core, which is important.) That piqued his interest and kicked off a few decades of hacking on Python.<p>He was an electrical engineering Ph.D. student and professor, and complex numbers are ubiquitous in that domain. Example:<p><pre><code> $ python3 -c 'print(3j * 2 + 1)'
(1+6j)
</code></pre>
This is another simple type built on Python's extensible core, and it's short.<p><pre><code> $ Python-3.9.4$ wc -l Objects/complexobject.c
1125 Objects/complexobject.c
</code></pre>
I recommend writing a Python extension in C if you want to see how it works. See Modules/xx*.c in the Python source code for some templates / examples. IMO the Python source code is a lot more approachable than Perl, Ruby, or any JS engine I've looked at.