Programming languages are complex even today at least to many programmers like me. But once you know the history of programming languages, you’ll definitely change your mind.
You might already know the computers understand only two symbols, zero (0) and one (1). Everything in computer is represented in form of zeros and ones. Everything means everything, whatever we see on computers like videos, images, applications, programs. Early programmers used to write computer program in zeros and ones. Can you believe that? They were genius man! They used to use binary readers like punch card, or switch board to load programs in computer. Those methods were still okay for small and simple programs but very difficult for large and complex program.
Considerable improvement happened with the introduction of assembly languages. This is great relief that the programmers now don’t need to write problem in machine language (using 0 and 1). But still they had to write program using mnemonic instructions like mov, jump, add etc. Instruction sets that were used in assembly program are very much possessor specific. As a result these types of programming are not portable at all.
High Level Language
In 1950s and 60s, high-level programming languages like Fortran, Pascal started coming. Instead of low level mnemonic instructions, programmers now can use constructs like variables, loop, conditional operations, functional building blocks like procedures and functions. Programmers create the source files in a specific high level language and the compilers and linkers convert them into machine code. Programmers do not need to worry too much about the processor where the code will run. System specific compiler and linker can convert the programs into appropriate machine instructions for the target system (processor). Portability increased to great extent. But the compiled binaries remains non-portable. For example, if a program is compiled on Windows, the generated binary file (the exe or .so file) does not run on Linux system.
Virtual Machine Concept
To solve this problem, many programming languages like Java came out with the concept of Virtual Machine. The compiler will not generate the final machine instructions, instead they will generate byte codes that will run on top of Virtual Machines. These types of languages provide Virtual Machines for various platforms. That way the generated byte codes become portable across platforms.
In parallel with the compiler based programming languages, interpreter based scripting languages had also started coming. Here the source codes (also know as scripts) do not get compiled into executable binary but interpreted in time of execution. The interpreters itself run and take the scripts as inputs and interprets the commands in the scripts. Interpreting scripts means the the interpreter does whatever the commands in the scripts ask the interpreter to do. These scripts are highly portable. Interpreters are available for different platforms for a particular examples. Python, Matlab or Tcl are the examples of such type of languages.