DEV Community

Cover image for Python Should Learn from Javascript
Pan Chasinga
Pan Chasinga

Posted on

Python Should Learn from Javascript

If Javascript, an old language with so many flaws, could evolve like it did, Python could learn from it and step out of its ivory tower.

This isn’t a targeted attack on Python. It is a constructive opinion from a programmer who had started his career and spent years working with it. So brace yourself — Python is evolving slowly and could use the level of improvement Javascript has had.

Javascript has come a long way since being the most hated but widely-used scripting language of the web that was created in less than a month. With ES6 and the sister language Typescript (that arguably helped propelled JS ecosystem to a new height), Javascript is no longer an ugly language to be looked down to. For instance, it has changed dramatically from a callback-based language into promise-based and async-await syntax in what seemed like a blink of an eye compared to the rate Python moved to reach a unanimous support for v3.
A very impressive deed of Javascript, in my opinion, is its move toward functional programming. The syntax is clean, learning from the great functional languages like ML. This alone sprouted so many great improvements to the ecosystem such as React, ReasonML, and more. Let’s admit it, there’s a lot to love about modern Javascript compared to Python 3.
Until recently, Python had always been under tight moderation of its creator, Guido Rossum. While that had its good parts, the downside is the language’s slow development due to the bottleneck from the resistance of the creator.

Lambda what?

For example, Guido Rossum distaste for lambdas was well-known. Perhaps the goal of Python’s half-baked lambda syntax that I’ve always found clumsy and useless to this day has always been to keep users from using it in the first place.

x = lambda a : a + 10
Enter fullscreen mode Exit fullscreen mode

There is nothing wrong with this syntax, since many Lisp dialects also use the keyword lambda to initialize an anonymous function. However, being a whitespace-significant language and not expression-based, the lambda syntax of Python makes a cumbersome and ambiguous experience in applying lambdas:

x = lambda a : a + 10 (lambda b : b * 2))
Enter fullscreen mode Exit fullscreen mode

Now who says Python is still easy to read? This kind of beats the very reasons of lambdas, which are expressiveness and clarity. This appears ambiguous to me. Compared to the anonymous function syntax of ES6:

let x = (c => c + 2)(a => a + 10)(b => b * 2)(y);
Enter fullscreen mode Exit fullscreen mode

Although not the cleanest (the cleanest lambda syntax goes to Lisp), the applications are clear, considered you know it is right-associated. The only thing Javascript is missing is piping syntax, which would have made it an even more expressive programming tool.

let x = y |> (c => c + 2) |> (a => a + 10) |> (b => b * 2)
Enter fullscreen mode Exit fullscreen mode

map(function, iterable, …)

Admit it, you either hate or feel meh over mapping iterables in Python, or you might not even use it.
Most languages, including Javascript, treat mapping function as the iterable or iterator method. This removes the iterable from the argument list and makes it much clearer with the callback function being the last argument.

let nums = [1, 2, 3, 4].map(n => n * 2);
Enter fullscreen mode Exit fullscreen mode

Here is another map function in Rust:

let nums = [1, 2, 3, 4].iter().map(|n| n * 2);
Enter fullscreen mode Exit fullscreen mode

Some functional languages such as Haskell and Ocaml use the module:function approach, which is similar to what Python does. However, their expression-based syntax and unambiguous scoped variable binding makes the code readable and easy to get right. Here is a sample of a map function in Ocaml:

let nums = let double n = n * 2 in List.map double [1; 2; 3; 4]
Enter fullscreen mode Exit fullscreen mode

You need to do this in Python:

double = lambda n : n * 2
nums = map(double, [1, 2, 3, 4])
Enter fullscreen mode Exit fullscreen mode

You may think Python looks way cleaner here, which you may be right. But consider most use cases where you chain operators.

let nums = [1, 2, 3, 4]
   .map(n => n * 2)
   .filter(n => n > 2);
   .reduce((acc, current) => acc + current);
Enter fullscreen mode Exit fullscreen mode

In Ocaml, it’s just magical:

let nums = [1; 2; 3; 4]
  |> map (fun n -> n * 2) 
  |> filter (fun n -> n > 2)
  |> fold_left ( + ) 0
Enter fullscreen mode Exit fullscreen mode

I’ll leave you to write an equivalent in Python (HINT: It is impossible to read!)

Decorators

Decorators are my pet peeves. To me, they were the inflection point from Python mantra of “there’s only one way to do things” and the promise of a transparent, non-magical language.

def hello(func):                                                                                            
    def inner():                                                                                            
        print("Hello ")                                                                                     
        func()                                                                                              
    return inner                                                                                            

def name():                                                                                                 
    print("Alice")                                                                                         

# `hello` is a decorator function                                                                                          
obj = hello(name)                                                                                           
obj()  # prints "Hello Alice"
The short-handed version for this is:
@hello
def name():
    print("Alice")
if __name__ == '__main__':
    name()  # prints "Hello Alice"
Enter fullscreen mode Exit fullscreen mode

Decorators “hide” the logic essential and completely change the behavior of a “host” function it decorates, which is nothing short of magical to more than half of all Python users today. Albeit useful, it still puzzles me to these days why Python developers decided to adopt decorators.

Somehow, Javascript has found its niche in everything. However, its ES6 improvement and Typescript enhancement has made it even more enticing to users who dislike it (myself, for one, had become a serious Javascript user after ES6). Python similarly hold a very big niche, including web programming, data science, and machine learning, which warrant its ivory tower. However, today’s tools are evolving fast, and not changing seems like standing still waiting for a new kid on the block to beat it in the home court.

If you like my writing, please follow me on Twitter to get more of technical opinions. I’m also on Medium and would love to see you there!

Top comments (1)

Collapse
 
rmoskal profile image
Robert Moskal

Couldn't agree more. I often come up with a nice composed algorithm that I wind up partially rewriting into imperative form in python.