Python vs JavaScript
I wanted to give you guys some background as to why I decided to compare two very distinct programming languages.
I have a friend with more than 20 years of experience with C/C++ programming. Yesterday he called me and said - "I want to learn something new, which programming language do you think is the best to learn today?" I automatically answered - JavaScript, because of its popularity. Then I thought again, and told him - "you know what, maybe python – since Python is widely used in modern systems" He asked: and if you need to choose one? I couldn’t give him a definite answer. So, I have decided to go over the features of both languages side by side and let the readers decide.
In this article I will compare Python and JavaScript -- two interpreted programming languages.
I am fully aware that this would be something like comparing apples to bananas based on the fact that both are fruits. Python and JavaScript are both programming languages so I will compare their properties of programming languages.
I will cover in this article the main aspects you can consider with both languages: different programming styles / approaches, available libraries and their ease of use.
About the languages
We have two programming languages but before we dive into comparing them let's take a brief look on their history and goals to know better their intention and why they were created.
Python
Python itself is not a programming language but a language definition. There are various implementations and the one we know and treat as "Python" is CPython a C based implementation. Python features a dynamic type system and automatic memory management. It has a big standard library and many modules which were developed from the Python community.
The language supports different programming paradigms like object-oriented programming, functional programming, imperative programming and procedural programming which we will focus on later in this article (except procedural programming which is a type of imperative programming but JavaScript is not supporting it).
JavaScript
JavaScript was standardized in the ECMAScript language specification. It is highly used in websites to provide dynamic functionality which you cannot achieve with HTML and CSS only. It has support for standard applications like working with text, regular expressions, dates or arrays -- but the default implementation is missing networking or other I/O functionality which restricts it to the running environment. However there are other implementations and extensions to the default functionality to enable missing features. For example JQuery is a JavaScript library used in websites to give easy to use extensions to core JavaScript.
The language supports different programming paradigms like object-oriented programming, functional programming and imperative programming. JavaScript does not support procedural programming.
Even if JavaScript contains Java in its name they are distinct languages, have some similar syntax (like with C, C++) but they are completely different -- but Java enables you to run JavaScript.
And if you deepen your JavaScript knowledge you will encounter inconsistencies. So be careful and try out your code blocks if you encounter strange errors when you run your whole script.
REPL
The first thing I like to take a look at is when choosing a new programming language the availability of a REPL (Read-Eval-Print Loop) which gives you the opportunity to try out basic programming features without writing actual code. In some languages this would be a problem but scripting languages are ideal for this approach because they are interpreted and need no compilation to get your code up and running.
Beside this REPL is a good tool to take a look at differences between languages very quick -- and to see how division works. Actually this is the first thing I look at when trying out a new programming language because there can be differences. Big differences.
Later on in this article I will use these interactive interpreters to show you example code and their results so I suggest you take a look at this section too.
Python
For Python you get the REPL with the installation, you do not need any extra tools to install. To start the REPL (or interactive interpreter) you can simply call python or python3 depending on your installation details (for example on my computer I have Python 2.7 and 3.5 installed beside each other and python starts 2.7, python3 3.5).
Let's take a look at t simple example with basic arithmetic operations:
GHajba$ python3
Python 3.5.0 (v3.5.0:374f501f4567, Sep 12 2015, 11:00:19)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 3 + 5
8
>>> 3 - 5
-2
>>> 3 * 5
15
>>> 5 / 3
1.6666666666666667
>>> 5 % 3
2
>>> 5 ** 3 == 5 * 5 * 5
True
>>>
>>> '3' + '5'
'35'
>>> '3' - '5'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'str' and 'str'
And you can easily navigate with the arrow keys through previously entered commands.
JavaScript
For JavaScript there is no out-of-the-box REPL available just with Python. The main reason is that you run your code most of the time in the browser (exceptions are web applications which we’ll deal with later) and there are many on-line tools where you can try your code or you have a local web server set-up where you can easily try the code.
There are many solutions however: the Nashorn project delivered with the standard Java distribution. You can start the REPL by calling jjs on your command line. This works if you have added the Java bin folder to your PATH. There are several problems with jjs: you cannot navigate with the arrow keys through the previously entered commands and you cannot write multiline statements than you would do when writing a script (actually I assume jjs wants to work with minimized scripts).
An alternative solution is to install Node.js and use it's REPL. It would be for the future a good option because if you work with JavaScript on the server side you will end up with Node.
GHajba$ node
> 3 + 5
8
> 3 - 5
-2
> 3 * 5
15
> 5 / 3
1.6666666666666667
> 5 % 3
2
> '3' + '5'
'35'
> '3' - '5'
-2
Imperative programming
After having an REPL and knowing how it works, it is time to take a look at the programming paradigms supported by these two programming languages.
Imperative programming describes how applications operate and uses statements which change the state of the application.
To avoid code duplication we use functions to encapsulate common functionality and steer the flow with arguments provided to the function.
Python
As mentioned in the introduction, imperative programming style changes state and describes how an application operates. Let's see a simple example by summing up numbers in a list:
>>> lst = [1, 4, 6, 9, 12, 8, 3]
>>> sum = 0
>>> for i in lst:
... sum += i
...
>>> sum
43
As you can see here, we define a variable for our list and sum which will hold the sum of the numbers in the list. We utilize a for loop to go through every element in the list and add the vale of the actual element to the sum variable. In the end we display the result, the value of sum, which is 43.
This clock of code describes how we calculate the sum of numbers in a list in Python -- and the value of sum changes with each iteration of the for loop.
I mentioned that we use functions too when we want to encapsulate functionality. Calculating the sum of lists could be a task which repeats often in our application and writing every time the same (or similar) for loop would be too much trouble. Let's introduce a function and use that function to sum-up the numbers in our lists:
>>> result = 0
>>> list_1 = [1, 4, 6, 9, 12, 8, 3]
>>> list_2 = [1, 2, 3, 4, 5]
>>>
>>> def sum(lst):
... global result
... for i in lst:
... result += i
...
>>> sum(list_1)
>>> result
43
>>> sum(list_2)
>>> result
58
As you can see in the example above I stayed with state-changing implementation to emphasize imperative programming. I defined a variable called result which will be accessed in the sum function using the global keyword (without this keyword Python would treat result as a local variable and will raise an error because result was not defined prior its usage). In this case in every iteration the result variable changes its value and you cannot guarantee that if you call the sum function twice with list_1 the result will be the same.
What happens, if we call the function without a parameter?
>>> sum()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sum() missing 1 required positional argument: 'lst'
As you can see, it requires an argument. What if we want result not to change or just call the sum function without arguments? For this Python has a feature I really like: default values for function arguments:
>>> def sum(lst=[]):
... global result
... for i in lst:
... result += i
...
>>> result = 3
>>> sum()
>>> result
3
In this case the function sum is called without an argument and it works because we have assigned an empty list as a default value to the argument lst.
JavaScript
After taking a look at Python, it is time to see the imperative approach of JavaScript. I will use the same examples as previously: I will sum up numbers in a list.
> var lst = [1, 4, 6, 9, 12, 8, 3]
undefined
> var sum = 0
undefined
> for(var i = 0; i < lst.length; i++)
... sum += lst[i]
43
> sum
43
As you can see, here we need to define the variables like we did in Python. The REPL gives you undefined as a result if no return value is provided from the executed code -- in this case assignments. To iterate over the array of numbers we simply create a for loop and go through all the indexes of the lst array and add the actual element to the sum variable. Again, with every iteration we modify the value of sum -- we change the application state.
Now let's define a function which does the same:
> var list_1 = [1, 4, 6, 9, 12, 8, 3]
undefined
> var list_2 = [1, 2, 3, 4, 5]
undefined
> function sum(lst) {
... for(var i=0; i < lst.length; i++)
... result += lst[i]
... }
undefined
> var result = 0
undefined
> sum(list_1)
undefined
> result
43
> sum(list_2)
undefined
> result
58
Again: here we change the global state of the result variable inside the function sum.
Since the version of ES6 (ECMAScript 2015, which is already implemented by Node.js v7.0.0) you can use default variables for your function arguments just you do with Python:
> function sum(lst=[]){
... for(var i = 0; i < lst.length; i++) {
..... result += lst[i]
..... }
... }
undefined
> var result = 0
undefined
> sum()
undefined
> result
0
This makes JavaScript a bit more usable and more like Python. The drawback is that jjs currently does not support ES6 -- but it should not matter because modern browsers already do and this is what matters.
> function sum(x) {
... result += x
... }
undefined
> var result = 0
undefined
> list_1.forEach(sum)
undefined
> result
43
> list_1.forEach(sum)
undefined
> result
86
The example above is almost functional: we provide a function to the Array.forEach method which is executed for all elements. The drawback is in this case that it changes global state. However a nice feature in JavaScript is that you can use anonymous functions (which are defined right on the spot where you can use them). Using anonymous functions you can write the previous example like this:
> result = 0
0
> list_1.forEach(function(x){
... result += x
... })
undefined
> result
43
In this case we do not provide a defined function (no name and no later usage) but we add the function to use on the spot. This is a commonly used solution for client site JavaScript (JQuery for example) to provide features which are written and used only once and you do not want to define an extra function for it.
Functional programming (FP)
Functional programming treats computation as evaluating mathematical functions and the main idea behind it is that these functions do not change state and do not mutate data -- and for the same input you will get always the same result.
Imperative programming has functions too but not in the mathematical sense -- they are sub-routines which may change state and may not produce the same output for the same input.
However the most known feature of functional programming (or at least most developers say a language functional) is that you can pass functions around as arguments and store them in variables and call them later.
Python
The example will be the same as previously: I will sum-up numbers in a list but now with functional style approach.
>>> def sum(lst):
... result = 0
... for i in lst:
... result += i
... return result
...
>>> sum(list_1)
43
>>> sum(list_2)
15
>>> sum(list_1)
43
As you can see, in this case I have defined a function which calculates the sum of the lst argument and in every iteration it changes the state of the local result variable. The result is returned after the method finished the calculation.
As mentioned earlier, this kind of calculation is functional because it does not change global state and for the same input you get the same result.
An alternative way to calculate the sum of numbers in a list is to use the sum() function which is already built-in into Python:
GHajba$ python3
Python 3.5.0 (v3.5.0:374f501f4567, Sep 12 2015, 11:00:19)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> list_1 = [1, 4, 6, 9, 12, 8, 3]
>>> list_2 = [1, 2, 3, 4, 5]
>>>
>>> sum(list_1)
43
>>> sum(list_2)
15
>>> sum(list_1)
43
I mentioned, that in functional programming languages you can pass around functions as function arguments and store functions in different variables. Let's take a look at an example:
>>> my_sum = sum
>>> my_sum(list_2)
15
>>> def do(lst, func):
... return func(lst)
...
>>> do(list_1, sum)
43
As you can see: it works. You can pass around functions as arguments or rename them internally.
To read a bit more about functional programming and closures take a look at another blog article.
JavaScript
JavaScript has a bunch to offer in functional programming too. There are many methods on objects which accept a callback function which get executed if some event happens -- or if we look at the previous example: the forEach method of the Array prototype executes the provided callback function for each element in the array -- but in this case we have changed the application's state within the function call and this is not functional.
Let's dive right into an example and see, how it is done:
> function sum(lst=[]) {
... var result = 0
... for(var i = 0; i < lst.length; i++) {
..... result += lst[i]
..... }
... return result
... }
undefined
>
> var list_1 = [1, 4, 6, 9, 12, 8, 3]
undefined
> var list_2 = [1, 2, 3, 4, 5]
undefined
> sum()
0
> sum(list_1)
43
> sum(list_2)
15
> sum(list_1)
43
This was just the base case -- there exists some other methods in the Array prototype which can be used to simplify summing up numbers in an array: the reduce method.
> var list_1 = [1, 4, 6, 9, 12, 8, 3]
undefined
> list_1.reduce(function(previous, current) {
... return previous + current
... }, 0)
43
The reduce function takes 2 arguments: a reduction function which we provided as an anonymous function, and a start value, which is in this case 0 because we want to sum up the numbers. The reduction function itself takes two arguments which I have written as previous and current. The current is filled with the current element of the array like when you iterate over the array, the previous is filled with the return value of the reduction function -- or for the first iteration the base value we provide as a second argument to the reduce method, in this particular case 0.
And because we are programming functionally, we can re-use the reduction function: define it as a real function and re-use it for other sums:
> function sum(a, b) {
... return a+b
... }
undefined
> list_1.reduce(sum, 0)
43
> sum(13, 29)
42
> list_1.reduce(sum, -1)
42
Object-oriented programming (OOP)
Object-oriented programming uses objects which hold data in fields (or attributes) and some code called methods. The methods in objects should (in my opinion) restrict to working on the fields of the current object -- the only exception is comparison between two objects.
OOP uses classes or prototypes as base for inheritance, extension and reuse. But do not go too deep into OOP because I could fill a book about this programming approach and I do not have the space here to do this. So I will keep a minimal introduction how you can achieve OOP in your Python or JavaScript application.
Python
Python uses the class based inheritance model -- what I would summarize as we use classes to do OOP.
object is the most base class in Python (note that it is really written with a small o at the beginning), fortunately it is implicit so every time you create a class you do not have to tell, that it is a subclass of object.
class Developer:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
print('Hello, I am ' + self.name + '. I am ' + str(self.age) + ' years old.')
def year_passes(self):
self.age += 1
The above example shows you a class definition (without mentioning object). The __init__ function is the constructor, the self.name and self.value are instance variables of the class. As you can see, you do not have to declare them previously, it all happens when you define them in the constructor. The greeter method prints the current state of the object (objects are instances of classes), the year_passes method changes the state of the object by incrementing it's age by one.
As you can see, every method has the reference to an argument called self. This self is the this you may know from other programming languages which denotes the current instance of the object and allows access to its variables and methods. Without providing this self variable to class methods we would not be able to access the state of the class.
Now let's use this class:
>>> me = Developer()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
>>> me = Developer('GHajba', 32)
>>> me
<__main__.Developer object at 0x1030b1c50>
>>> me.greet()
Hello, I am GHajba. I am 32 years old.
>>> me.year_passes()
>>> me.greet()
Hello, I am GHajba. I am 33 years old.
Instantiating a class is easy: you just have to call the class' name with parentheses -- just like a function. If you need parameters to provide to the constructor, you have to add them too.
After calling the year_passes() method on the my_a object we see, that the state of the object has changed and the years have been incremented by 1.
JavaScript
Opposite to Python, JavaScript uses the prototype based inheritance model.
The nice thing about this model is that you can change the behavior of different objects by extending their codebase through their prototype. For example you have an array and you want to get the sum of all elements of that array. There are some options: you write a function which does this (because you do not want code duplication, right?) like we did previously, use the built-in reduce method on the array, or you can add the function directly to the Array class and call your sum function on every array you like:
> Array.prototype.sum = function() {
... result = 0
... for(var i = 0; i < this.length; i++) {
..... result += this[i]
..... }
... return result
... }
[Function]
> var list_1 = [1, 4, 6, 9, 12, 8, 3]
undefined
> var list_2 = [1, 2, 3, 4, 5]
undefined
> list_1.sum()
43
> list_2.sum()
15
But what is the basis which enables all this? Well, the answer is simple: in JavaScript classes are constructor functions. This means you need to define a function when you would define a class in other languages:
Developer = function(name, age){
this.name = name
this.age = age
this.yearPasses = function(){
this.age += 1
}
this.greet = function(){
return "Hello, my name is " + this.name + ". I am " + this.age + " years old."
}
}
Above you can see the definition of a new object called Developer just like in the Python example. Now let's instantiate an object:
> me = new Developer()
Developer {
name: undefined,
age: undefined,
yearPasses: [Function],
greet: [Function] }
> me.greet()
'Hello, my name is undefined. I am undefined years old.'
> me.yearPasses()
undefined
> me.greet()
'Hello, my name is undefined. I am NaN years old.'
As you can see, JavaScript does not raise any error if you do not provide the constructor arguments -- it defaults the values to undefined and this can lead to various errors later in your code. But let's fix this and provide the required parameters to the constructor:
> me = new Developer('GHajba', 32)
Developer {
name: 'GHajba',
age: 32,
yearPasses: [Function],
greet: [Function] }
> me.greet()
'Hello, my name is GHajba. I am 32 years old.'
> me.yearPasses()
undefined
> me.greet()
'Hello, my name is GHajba. I am 33 years old.'
Now everything works fine.
But this is only one side of a coin. On the other side you have objects which are associative arrays -- I would say they are similar to struct in C/C++ with the difference that you can add a function to it too -- which modifies state:
> me = {
... name: "GHajba",
... age: 32,
... greet: function(){
..... return "Hello, my name is " + this.name + ". I am " + this.age + " years old.";
..... },
... yearPasses: function(){
..... this.age += 1;
..... }
... }
{ name: 'GHajba',
age: 32,
greet: [Function: greet],
yearPasses: [Function: yearPasses] }
> me.greet()
'Hello, my name is GHajba. I am 32 years old.'
> me.yearPasses()
undefined
> me.greet()
'Hello, my name is GHajba. I am 33 years old.'
This is one way to create an object fully initialized. Naturally this version has the drawback that you need to define the methods every time you create a new object. This means use this approach only if you have one instance with this kind of functionality, otherwise just use prototyping with constructor function.
Conclusion
We have taken a bird's-view look at Python and JavaScript to see which could fit better for your purposes. The coding styles presented in the article can be mixed up when you develop an application -- in my opinion they should be used with each other because they provide you solutions which you cannot fully achieve with only one approach or you need too much effort to solve that particular problem.
The difference between the two languages are small: you can do almost everything with both -- and if some feature is missing, you will find a library which gives you that particular feature. Even for multi-threading in JavaScript exist libraries and solutions so you are not left alone.
If you ask me, which programming language you should learn -- to get a job or just out of sheer curiosity, I will suggest you to learn Python and then learn JavaScript. That's because with JavaScript you can get a good job (JS developers are needed everywhere around the globe) but you need to know a programming language which gives you constraints and good basics in real software development because these are missing from JavaScript. If you start with JavaScript it will be hard to accommodate to the constraints and language constructs other programming languages offer.
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment