Python Should Learn from Javascript
Tags: python, javascript, rust, ocaml
Published: 2021-07-16 04:16:48


> 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.

```python
x = lambda a : a + 10
```

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:

```python
x = lambda a : a + 10 (lambda b : b * 2))
```

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:

```javascript
let x = (c => c + 2)(a => a + 10)(b => b * 2)(y);
```

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.

```javascript
let x = y |> (c => c + 2) |> (a => a + 10) |> (b => b * 2)
```

# 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.

```javascript
let nums = [1, 2, 3, 4].map(n => n * 2);
```

Here is another map function in Rust:

```rust
let nums = [1, 2, 3, 4].iter().map(|n| n * 2);
```

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:

```ocaml
let nums = let double n = n * 2 in List.map double [1; 2; 3; 4]
```

You need to do this in Python:

```python
double = lambda n : n * 2
nums = map(double, [1, 2, 3, 4])
```

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

```javascript
let nums = [1, 2, 3, 4]
   .map(n => n * 2)
   .filter(n => n > 2);
   .reduce((acc, current) => acc + current);
```

In Ocaml, it’s just magical:

```ocaml
let nums = [1; 2; 3; 4]
  |> map (fun n -> n * 2) 
  |> filter (fun n -> n > 2)
  |> fold_left ( + ) 0
```

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.

```python
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"
```

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](https://twitter.com/pancychain) to get more of technical opinions. I’m also on [Medium](https://medium.com/@pancy) and would love to see you there!