DEV Community

loading...

JavaScript is almost pythonic

massa142 profile image Masataka Arai Updated on ・3 min read

Multi-line String

  • Python3.6
print("""string text line 1
string text line 2""")
  • ES2017
console.log(`string text line 1
string text line 2`)

Expression Interpolation

  • Python3.6
a = 5
b = 10
print(f'Fifteen is {a + b} and not {2 * a + b}.')
  • ES2017
var a = 5
var b = 10
console.log(`Fifteen is ${a + b} and not ${2 * a + b}.`)

Arrow function

  • Python3.6
numbers = [1, 2, 3, 4]

list(map(lambda x: x * 2, numbers))
# or [x * 2 for x in numbers]
  • ES2017
var numbers = [1, 2, 3, 4]
numbers.map(v => v * 2)

Destructuring

  • Python3.6
numbers = (1, 2, 3)
x, y, z = numbers
  • ES2017
var numbers = [1, 2, 3]
var [x, y, z] = numbers

Spread Operator

  • Python3.6
import datetime
date_fields = (2017, 12, 4)
date = datetime.date(*date_fields)

numbers = [1, 2, 3, 4]
first, *remaining = numbers

first = [1, 2]
second = [3, 4]
combined = first + second
  • ES2017
var dateFields = [2017, 12, 4]
var date = new Date(...dateFields)

var numbers = [1, 2, 3, 4]
var [first, ...remaining] = numbers

var first = [1, 2]
var second = [3, 4]
var combined = [...first, ...second]

Rest Operator

  • Python3.6
from functools import reduce
def product(*numbers):
    return reduce(lambda x, y: x * y, numbers)

print(product(1, 2, 3, 4))
  • ES2017
function product(...numbers) {
    return numbers.reduce((x, y) => x * y)
}
console.log(product(1, 2, 3, 4))

Default Parameter

  • Python3.6
def multiply(a, b=1):
    return a * b
  • ES2017
function multiply(a, b = 1) {
  return a * b
}

Class

  • Python3.6
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __str__(self):
        return f"({self.x}, {self.y})"
  • ES2017
class Point {
    constructor(x, y) {
        this.x = x
        this.y = y
    }
    toString() {
        return `(${this.x}, ${this.y})`
    }
}

Sub Class

  • Python3.6
class ColorPoint(Point):
    def __init__(self, x, y, color):
        super().__init__(x, y)
        self.color = color
    def __str__(self):
        return "{} in color {}".format(super().__str__(), self.color)
  • ES2017
class ColorPoint extends Point {
    constructor(x, y, color) {
        super(x, y)
        this.color = color
    }
    toString() {
        return `${super.toString()} in ${this.color}`
    }
}

Getter & Setter

  • Python3.6
class SmartPoint(Point):
    @property
    def hypotenuse(self):
        return sqrt(self.x ** 2 + self.y ** 2)

    @hypotenuse.setter
    def hypotenuse(self, z):
        self.y = sqrt(z ** 2 - self.x ** 2)
  • ES2017
class SmartPoint extends Point {
    get hypotenuse() {
        return Math.sqrt(this.x ** 2 + this.y ** 2)
    }
    set hypotenuse(z) {
        this.y = Math.sqrt(z ** 2 - this.x ** 2)
    }
}

Module

  • Python3.6
import math
print(math.log(42))

from math import log
print(log(42))

from math import *
print(log(42))
  • ES2017
import math from 'math'
console.log(math.log(42))

import { log } from 'math'
console.log(log(42))

import * from 'math'
console.log(log(42))

Async Function

  • Python3.6
async def getProcessedData(url):
    try:
        v = await downloadData(url)
    except Exception:
        v = await downloadFallbackData(url)
    await processDataInWorker(v)
  • ES2017
async function getProcessedData(url) {
  let v
  try {
    v = await downloadData(url) 
  } catch (e) {
    v = await downloadFallbackData(url)
  }
  return processDataInWorker(v)
}

Reference

Discussion

pic
Editor guide
Collapse
aspittel profile image
Ali Spittel

I just really want indentation instead of brackets for code blocks! Then JavaScript will officially be fully Pythonic.

Collapse
zzzzbov profile image
Timothy

You've just described CoffeeScript.

Collapse
aspittel profile image
Ali Spittel

True, CoffeeScript is heavily influenced by Python! I do think it usually causes more pain than its worth to add something like that in though.

Thread Thread
muresanandrei1 profile image
Muresan Andrei

Isn't CoffeeScript influenced by Ruby?

Thread Thread
aspittel profile image
Ali Spittel

According to wikipedia: "CoffeeScript is a programming language that transcompiles to JavaScript. It adds syntactic sugar inspired by Ruby, Python and Haskell in an effort to enhance JavaScript's brevity and readability."

The indentation is definitely Pythonic.

Collapse
ben profile image
Ben Halpern

Yep, CoffeeScript is a good idea except that this kind of syntax-driven transpiling never seems to be worth it. Maybe pre-ES2015 but I can't imagine CoffeeScript living much longer besides legacy.

Thread Thread
brentsmind profile image
Brent

I disagree. If you have to use a build step to convert JavaScript into older JavaScript to get all of it's best features using another syntax is just as okay. Use Elm use ClojureScript use CoffeeScript use whatever you're comfortable with.

Thread Thread
ben profile image
Ben Halpern

I agree with you, but what I was trying to say is that with JS's improvements, CoffeeScript isn't offering as much. A lot of the benefits are now native, so the CoffeeScript community shrinks and the tradeoffs of fewer people understanding it are no longer worth the trouble.

Elm and ClojureScript bring more than syntactic sugar to the table. Same with TypeScript.

Use CoffeeScript if that's what you like, but I think the benefits have faded of late.

Thread Thread
brentsmind profile image
Brent

I haven't really used it myself but the community seems to have some really dedicated people. I believe they just released a new version to put it more in line with modern js.

So I'd hate to stop a potential user from trying it because they read this and didn't think it was worth a glance.

The JS comminity owes them a lot cause es6 wouldn't be what it is without coffeescript so hopefully they keep doing innovative stuff that ends up coming over to us.

Thread Thread
slmyers profile image
Steven Myers

The JS comminity owes them a lot cause es6 wouldn't be what it is without coffeescript so hopefully they keep doing innovative stuff that ends up coming over to us.

I think this is a little off the mark. This thread was discussed the influencing factors for coffeescript and this post showed how js is similar to a coffeescript influence (python). Personally, I think it's more accurate to thank python for doing innovative stuff that "ends up coming over to us". Repositories like this highlight how cs is waning.

Collapse
kayis profile image
K

How about BuckleScript, a OCaml compiler back-end that eats OCaml and spits out JavaScript?

Looks pretty Pythonic to me:

let rec hanoi n a b c =
  if n > 0
  then
    (hanoi (n - 1) a c b;
     Js.log {j|Move disk from pole $a to pole $b|j};
     hanoi (n - 1) c b a)
let _ = hanoi 4 1 2 3
Collapse
aspittel profile image
Ali Spittel

woah that looks super Elm-ish to me

Thread Thread
nepeckman profile image
nepeckman

They actually share roots! OCaml and Elm are both in the ML family of programming languages.

Thread Thread
johnpaulada profile image
John Paul Ada

I had a better time learning Reason and BuckleScript than learning Elm though LOL but hey as long as it's functional I'm all for it

Collapse
johnpaulada profile image
John Paul Ada

Yeah plus all the types and all the goodness 😄

Collapse
idanarye profile image
Idan Arye

That will be a problem for minimizers

Collapse
aspittel profile image
Ali Spittel

True, this is kind of half joke, half dream scenario. You would probably need automatic bracket insertion similar to the automatic semi-colon insertion that exists now!

Collapse
ayman_1012 profile image
Ayman Aladdin

no way 😂 i hate indentation

Collapse
rpalo profile image
Ryan Palo

Do you know if JavaScript has anything approaching comprehension syntax? That would be extra pythonic!

From your "Arrow Function" section:

numbers = [1, 2, 3, 4]
list(map(lambda x: x * 2, numbers))

Generally (and you probably know this), you see this in Python as:

numbers = [1, 2, 3, 4]
[x * 2 for x in numbers]
# => [2, 4, 6, 8]
Collapse
zzzzbov profile image
Timothy

Array comprehensions existed briefly but didn't receive enough support to become standardized so they were dropped. I expect they may come back in the future.

Collapse
aspittel profile image
Ali Spittel

Yeah, I don't think the syntax was quite as clean as Python's but I love that feature in Python and hope it comes back to JavaScript.

Collapse
brentsmind profile image
Brent

You can get rid of the semicolons as well. I use prettier in VS Code and it automatically does it for you.

Collapse
uegnet profile image
uegnet

Newbie question, what is the performance hit for auto insertion?
I mean when the interpreter does it, "live"

lh3.googleusercontent.com/hX39h-wD...
If it's a large app, this seems like a lot 😅

Collapse
aspittel profile image
Ali Spittel

I totally agree with Evan You (who wrote Vue) on this one slides.com/evanyou/semicolons#/

Collapse
jvarness profile image
Jake Varness

It kinda seems like languages are all becoming each other, haha. I can draw a lot of similarities here to Dart. I'm sure some folks would find that a lot of the same features listed here are also in other languages like Kotlin and Swift.

Collapse
sam_ferree profile image
Sam Ferree

Almost all of these C# can do.

Collapse
r0f1 profile image
Florian Rohrer

To add to the Getter & Setter examples: You can use this in Python instead of self. It is just a convention, that people refer to the current instance as self. Also, instead of sqrt in both languages, you can write **0.5. With both modifications, that codes look even more similar.

About the classes example: They might look similar, but they are not. __init__ is not a constructor. __init__ is an initializer. The constructor in Python is called __new__. Also, usually you override __repr__ to get a representation of the object instead of __str__.

Collapse
math2001 profile image
Mathieu PATUREL

Hmm... Good comparaison, JS is definitely getting better, but still.

Quick thougts:

Everything is an Object in JS (including arrays), there isn't any proper equivalent of python's magic functions (add for example).

One thing that horrifies me: how to convert a integer to string: '' + 2.

I think JS' ecosystem is awesome, but JS in itself absolutely sucks. Pretty much the opposite of Python.

Collapse
schnubb profile image
Schnubb

There's a method for that:

const x = 2;
x.toString(); // "2"
Collapse
elarcis profile image
Elarcis

Or as an alternative, String(x), which does exactly the same thing, except if x is null or undefined, then it produces 'null' or 'undefined' instead of throwing an error.

Collapse
elarcis profile image
Elarcis

No need to be that categorical in your judgement, your '' + 2 code sample has always been outdated, as String(2) or (2).toString() have been allowed since the 1997 standard (source).

It’s possible to do awful code in a lot of languages, Python included, finding the worst in a tech is not a proof of it “sucking” ;)

Collapse
codemouse92 profile image
Jason C. McDonald

Javascript cannot be Pythonic until it has Python's rules of dynamic typing, mutability/immutability, and equivalence. It would also need to iterate in the same manner. See Facts and myths about Python names and values and Loop Like a Native by Ned Batchelder for excellent explanations.

Collapse
jbendelbrot profile image
Joshua Bendelbrot

I'd better keep apart semantics and tinkering with lang:

JS:

0 in [1,2,3] === true
1 in [1,2,3] === true
// Wrong usage because JS expects Object

Python:

(0 in [1,2,3]) == False
(1 in [1,2,3]) == True

But, JS:

'1' in {'1': null} === true // correct

and Python:

(1 in {1: None}) == True

Thus historically JS is much more ad-hoc with all the consequences.

Collapse
lietux profile image
Janne "Lietu" Enberg

It takes more than a few specific capabilities to be "Pythonic".

PEP-20 for example is pretty core to Python: python.org/dev/peps/pep-0020/

I find it unlikely that JS's poor organization will ever reach a level where they could be considered Pythonic, even though they do make (often sloppy) copies of features from (among other things) Python.

Collapse
lewiscowles1986 profile image
Lewis Cowles

:( Kinda gutted that JS extends syntax looked a lot cleaner.

I have to fight to not use braces if I switch between Python & JS, even though they waste space and the language doesn't enforce (eslint is a tool, it's not language enforced like python).

Here's my tweet response twitter.com/LewisCowles1/status/10...

Collapse
yellow844 profile image
y_hashi

I was worried that the variable declaration of the sample code is var though using ES2017.

Collapse
emmanuelobo profile image
Emmanuel Obogbaimhe

I noticed these similarities when working with Django. So often I accidentally code with Python syntax in JS or vice versa

Collapse
xowap profile image
Rémy 🤖

It sure makes JS more usable. Still, the "insides" keep on being messy, there is many holes around and so on. But yup it's moving towards a direction that I like.

Collapse
antonfrattaroli profile image
Anton Frattaroli

Looks a lot more like C# to me. If ES2017 had access modifiers it'd be nearly identical.

Collapse
apastuhov profile image
Aleksey Pastuhov

Just have a look on the TypeScript :)

Collapse
webknjaz profile image
Sviatoslav Sydorenko

Yeah, I've noticed this some time ago.
Don't forget that you also can omit semicolons in JS as well :)

Collapse
zalithka profile image
Andre Greeff

Very interesting comparison, thanks for the nice clear examples.. :)

Collapse
mauricehayward profile image
Maurice Hayward

Cool! Also, closure works the same in Python and Javascript.

Collapse
vidja profile image
VidJa

The best thing that happened to me was when I presented some working python code and the guy on the front row asked me when I was going to implement the pseudocode example.

Collapse
dfockler profile image
Dan Fockler

I'd say it's even more like Ruby, but everyone already says that Ruby and Python are similar.

Collapse
kzagoris profile image
Konstantinos Zagoris

It looks more like C#. if you consider Typescript instead of JavaScript is uncanny similar

Collapse
paddy3118 profile image
Paddy3118

Just waiting for ES202? == Python, you might as well...

Collapse
lepinekong profile image
lepinekong

Great that's what I just needed ;)

Collapse
jesuszilla_tm profile image
Jesuszilla イエスジラ

Nice article! Also HAGGAR

Collapse
prasad_h profile image
Prasad Honavar

Wow didn't know JavaScript became cool😁