Introduction
There are thousands of programming languages in this world. Some of them are
called compiled languages and the software we use for the language is called
compiler. Some of them are called as interpreted languages. The softwares we use
for them are called interpreter. Another interesting fact is that for every
compiled language, an interpreter can be built but the reverse is impossible.
That is, all the interpreted languages can not be a compiled language. Either
Being interpreted or compiled is not the property of the programming languages
but, design of some languages make them unsuitable for native code generation.
This article describes the advantages and disadvantages of both natively
compiled and those are not natively compiled. This is my first article and I
have not well practiced in writting yet.
Compiled and Interpreted
languages
Natively Compiled Languages
A natively compiled language is a programming language that have compiler(s)
built for it which can compile the source code to native code. A natively
language can always be an interpreted language. Take for an instance C++ is a
natively compiled language. But it also has a number interpreters like CINT, ch
interpreter etc., This is because of the constrains of the native code. The
natively compiled languages are created in such a way to suit the constrains but
the interpreted languages are not.
Interpreted Languages and JIT Compiled (Not compiled to native code)
In some cases, the source code is executed line by line by a software called
interpreter. Interpreted languages are often slow than the compiled languages
because of a number of reasons. It is because the source should be executed line
by line. Also the interpreted languages like python and even Java, C# have a
number of advanced facilities like dynamic typing, type checking, extensive type
information which would be stored in the interpreter reduces the performance of
the interpreted applications. Another disadvantage is that one should have the
interpreter installed in the computer unless the interpreter is embedded in the
software which may increase the size of the package. For example, Blender has embedded python interpreter.
Direct execution of the source code
This is where the source files of interpreted languages are directly executed
by the interpreters without any step of changing it to an intermediate or
bytecode form. Some web scripting languages like PHP, JScript and VBScript works
based on direct source execution. Some of them may have Just-In-Time compilation
but they only don't get their source converted to a bytecode form.
Compiling to a Bytecode
There are some compilers or frameworks which convert source code of certain
programming languages to an intermediate language that is embedded in a
executable or any sort of file. Then the virtual machine or interpreter executes
the intermediate language during the runtime of the application. These kind of
applications are rather fast than that have it source interpreted. Sometimes,
there is another sort of execution known as Just-In-Time execution(JIT) where
the bytecode is converted to native code during runtime by the interpreters and
executed. This methodology proved to improve the peformance of interpreted
languages. Even though then they are slower than natively compiled languages.
Microsoft's .NET Framework and some implementations of Java work based on this
principle. Compiling to a Bytecode comes under the category of interpreted
languages
Advantages of Interpreted and JIT Compiled languages
General Advantages
We have already spoken about the disadvantages of the interpreted languages
and JIT Compiled languages. Even though they have many disadvantages they have a
number of advantages. Firstly interpreted languages saves compile time resulting
in faster development. This makes them ideal for scientific and mathematical
computing. They also provide many features that aren't accessible in compiled
languages. They are also very suitable for scripting. For example Microsoft Word
provides scripting capabilities by interpreting Visual Basic code. If you write
an application which you need to seamlessly interact with the user, then
scripting is one of the choices. It also enable them to automate tasks reducing
their appetite. Interpreted languages like JScript, VBScript, PHP are good
choice for Web Programming. This is because they can't be compiled for each and
every platform and device while its loading. Suppose if a web page is loaded in
a Linux Machine, and it contains C++ code, it can't be compiled for that
machine. So interpreted languages play an inevitable role in web programming.
They run whatever the device or machine is if viewed in a browser supporting
them. For example viewing a web page containing JScript in Google Chrome in
computer and in an Android Tablet produces the same results. Java is often
referred to as an interpreted language. Java source code is converted to byte
code. Java is not popularly used as a desktop programming language but it finds
its use in many other places like Web, Mobile phone programming, Android
Programming etc., For instance, Take Google's Android OS. It has a Linux kernel
and so one can create software using ARM compilers. But Google did not do that.
Android has a Virtual Machine named Dalvik which executes Dalvik byte code. For
some reason they didn't embed a Java VM. They provided tools to convert Java
bytecode to Dalvik Bytecode. The reason for why they prefer Java over C++ is
that Java has a large community which may lead to the rapid increase of apps in
their store. Java is also a powerful Object Oriented Programming language. The
Android apps running on Dalvik VM does not provide full performance. Although
there were no visible effects on performance, Google has released Android Native
Development Kit(NDK) which allows the users to speed up the critical pieces of
code by the Native Code. Android NDK provides a way for creating parts of apps
using C and C++ ARM Compilers.
Extending your application
Scripting languages also provide a great platform for writing extension or
plugins for your applications without loading Dynamic link libraries or Shared
Objects dynamically. This can reduce the difficulty in writing a plugin for a
particular application. The traditional way of writing a plugin involves
creating a DLL which requires the compiler and also the libraries used by the
applications. Many modern applications provide way for creating plugins using
scripting languages like Python.
Cross platform support
Cross platform programming is always been difficult and a software clinging
to a single platform can seriously affect the range of audience. If you create a
software in a compiled language you have to move the source from machine to
machine and compiling the source in that machine. But executing the source by
the interpreter does not stick to a single platform only if the code itself is
not platform dependent. Producing platform independent code has not always been
an issue. Suppose if you create a python application using Windows and want it
to be platform independent then don't use platform specific features like
Component Object Model(COM) which is available only under windows. Java follows
the policy of "Write Once, Run anywhere". But .NET is not cross platform. It is
much more suited for Windows but there are many variants of .NET like dotGNU
that are cross platform. Even there is a .NET based framework available for
Android!!
Java and .NET supports Reflection
Java and .NET languages support an excellent feature called reflection. Using
reflection one even can create a method or class in runtime and use it. Even a
dozen of .NET languages rose only because of reflection feature. They support
seamless object serialization without any external library. Even an assembly can
be disassembled using reflection. But one should be aware that every .NET and
Java assembly can be re engineered using the same reflection feature. This
danger can be overcome by using obsufcators. See this page for a list of .NET
obfuscator.
Wide Range of Devices
Usage in wide range of devices where performance limits is another advantage
of languages that aren't converted to native code. Take Java Micro Edition, it
is available in wide range of devices even in mobiles that aren't smart phones.
It allows the use of a powerful object oriented programming language to create
apps for an unadvanced device. The Java installer claims that Java runs on more
than 3 billion devices. Python interpreter is available for Android devices(QPython
for Android) enabling the users to perform advanced calculations using a
handy device. No one can compile an applicaton to native code and run in a J2ME
Device where there is actually no Operating System.
Smaller executables and packages
It is obvious that the executables of interpreted applications are of very
low size than that of the compiled languages. It is interesting to note that in
a C# application is embedded the Intermediate language which is not machine
language. It is the same case in Java and this dramatically can reduce the size
of the executables. No one should deny that Python libraries like wxWidgets are
created using C++ and connected by SWIG. But the size of wxWidgets library for
Python is less than for that of C++.
Easily debuggable
Bugs are often the headaches of programmers. .NET Languages and other
interpreted languages provides facilities so that bugs can be caught easily.
They throw an exception and the details of the exception will be clearly
furnished in a dialog box. Unlike native code which only indicates an error is
there managed code even show an error even that an object that is not
initialized and also indicates the name of the object. This easily eradicates
bugs. For an instance if your application is distributed with a bug and the user
sees an error message then the user can be intimated to send the error report.
It enables us to easily locate the error in the source code rather than
searching for it.
Side by Side code execution
This is one of the features that are unique to the interpreted languages.
This feature is unavailable in C# or Java. Programming languages like Python, J,
R have the console or GUI command prompt based softwares where code is executed
on the fly. They are also referred to as "shell". They also report errors on the
fly. This can provide a concrete facility for learning.
Advantages of the compiled languages
Speed
Compiled languages are always supposed to be fast because of their direct
execution by the computer. Speed and performance can change programmers
preference. Especially for large projects, speed and performance is
indispensable. Poor speed can crush user experience and can annoy them. C is
claimed to be the fastest programming language next to assembly code. It is
believed that C is faster than C++ is some instances. One website even says that
some algorithms implemented in python may run ten times slower than its
equivalent written in C++. It is also obvious that speed always does not matter.
There can be places where speed is secondary.
Native applications are secured
Even though native applications can be disassembled, the assembly code is not
so clear and the source code can not be that easily obtained. For example it is
possible to generate C# code from a .NET assembly using some tools but it is
impossible to generate C++ code from an executable.
Large softwares are written in Compiled Languages
Large softwares and million dollar projects are often written in compiled
languages because of the speed and performance they offer. Many large softwares
with huge code bases ranging from Office suites, IDEs, Compilers, Games, time
and mission critical applications were written in compiled languages. You can
even observe in your computer many softwares are natively compiled. Even the web
browser you are viewing this page may be written in compiled languages. Browsers
are compiled natively because they need speed. But the parts of a large software
may be written in interpreted languages. It is to be noticed that your browser
uses many interpreted languages like JScript, VBScript, PHP etc., to view web
pages.
Reflection is not impossible
Reflection is not impossible in compiled languages. It is possible with third
party libraries like GNU
lightning, Boost
Serialization etc., Thus it is not true that reflection is impossible in
compiled languages. It saves us from creating XML or any other sort of IO
routines which saves our data textually for every persistent data which is time
consuming. Some programmers prefer saving their data in binary form rather than
simply saving in a textual manner. But writing compilers for native languages
that can emit machine code is an advanced step though then there are some
libraries like ASMJIT that can
be used for real time machine code generation.
Interoperability is possible with .NET, Java and Python
It is possible for a natively compiled application to use .NET(through COM),
Java libraries and Python source codes. So if you have a large investment in
interpreted languages and planning to move to compiled languages, you can still
use your libraries that you have created for .NET, Java and python. There is an
option of using .NET controls in your MFC Applications. .NET Assemblies can be
accessed by creating a COM wrapper from any program.
Why aren’t there compilers for some interpreted
languages?
Already the article discussed about the impossibility of creating compilers
for some interpreted languages due to the some limitations in converting them to
machine language. It does not mean that there can't be a compiler for every
interpreted language. Java has a native code compiler(GNU Java Compiler). Python does not have
native compilers that can compile native code to machine language. Python
converts the source to a byte code file with an extension (.pyc). But the source
can be converted to executables and though then, it is interpreted. In this case
the code is embedded in the executable and then executed by the Python
interpreter embedded in it. It doesn't have any effect but helps the program to
be closed source. Some of the features that limit the compilation to native code
are:-
In Python, Functions do not indicate their return types until the end of the
function is executed. It is not even known by interpreter whether an object will
be returned or not before the actual execution of the routine. This sort of
dynamic typing can be impossible in machine code. Consider the following program
import random;
def method():
generated = random.randrange(6);
if(generated / 2 == 0):
return "It is even";
if(generated / 2 == 1):
return 1;
return 0; ## Impossible
print(method());
print(method());
print(method());
The output came as follows :
It is even
It is even
1
The output may differ every time you execute it and so it is
impossible to generate an assembly language representation of this program.
What about the templates in the C++ or D programming language?
Templates in C++ or D are different from the dynamic typing
as done in python programs. They are nothing but similar to a macro. The type
of the object is defined in the compile time and not in the runtime as done in
the above program. Consider the following C++ source code.
#include <iostream>
#include <conio.h>
#include <typeinfo>
using namespace std;
#define INT 0 // Return an integer
#define STR 1// Return a string
template <class T>
void method(T val)
{
if(!strcmp(typeid(val).name(), "int"))
{
cout<<"The variable is an integer"<<endl;
}
else if(!strcmp(typeid(val).name(), "double"))
{
cout<<"The variable is a double"<<endl;
}
}
void main()
{
method<int>(3);
method<double>(2.4);
getch();
}
The above program is an example of function templates in C++ which would yield
the following output,
The variable is an integer
The variable is a double
The first time the method is called the template parameter is "int" and so while
compiling the function a C++ compiler would change all the objects whose type
names are declared T to "int" and so the type identification function informed
the type the variable "var" as "int". These all occur only in the compile time.
Some python functions like "eval()" always require the Python parsing system
and runtime system. In C++, a class is
compiled in entirely different way unlike as in C# or Java. Consider the
following C++ code
class ABC
{
public:
int a;
ABC()
{
}
void Method1()
{
}
void Method2()
{
}
};
int main()
{
ABC abc;
abc.a = 10;
abc.Method1();
return 0;
}
The code contains a class named "ABC" which have "Method1" and the class
has been instantiated in the main() function. I converted the source to an
assembly representation by the MinGW C++ Compiler using "-S" Option(Case
Sensitive) and the assembly looked as the following,
.file "m.cpp"
.def ___main; .scl 2; .type 32; .endef
.text
.align 2
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
movl %eax, -8(%ebp)
movl -8(%ebp), %eax
call __alloca
call ___main
subl $12, %esp
leal -4(%ebp), %eax
pushl %eax
call __ZN3ABCC1Ev
addl $16, %esp
movl $10, -4(%ebp)
subl $12, %esp
leal -4(%ebp), %eax
pushl %eax
call __ZN3ABC7Method1Ev
addl $16, %esp
movl $0, %eax
leave
ret
.section .text $_ZN3ABC7Method1Ev,"x"
.linkonce discard
.align 2
.globl __ZN3ABC7Method1Ev
.def __ZN3ABC7Method1Ev; .scl 2; .type 32; .endef
__ZN3ABC7Method1Ev:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl $10, -4(%ebp)
leave
ret
.section .text $_ZN3ABCC1Ev,"x"
.linkonce discard
.align 2
.globl __ZN3ABCC1Ev
.def __ZN3ABCC1Ev; .scl 2; .type 32; .endef
__ZN3ABCC1Ev:
pushl %ebp
movl %esp, %ebp
leave
ret
You may observe that there is no class definition in the assembly code.
The class definition is only stored in the symbol table of the C++ compiler. You
may see that the variable "a" is used in the main function and yet there is no
variable of the class ABC. The variable "a" is just stored in a local
variable(see the comments). The method is stored as "__ZN3ABC7Method1Ev" as we
called it from the main function; you may be surprised to see that there is no
definition of Method2. It is because we didn't use it. The compiler decides to
include a field or function only if it is used. It is clear that class "ABC" is
stored in the symbol table of the compiler and then if a field is used the
compiler includes it in the assembly. Here we used Method1 so the compiler
included the Method in the assembly with the name "__ZN3ABC7Method1Ev". And when
we called the function you may note the statement "call
__ZN3ABC7Method1Ev". This is the actual method by which OOP native compilers
compile code to native code.
Above we discussed about how a native C++ compiler compiles a class. The
following is the way a C# compiler compiles a class. Consider a class named
"ABC" which has a variable "a" is compiled to a .NET executable then the
following is the disassembly. The namespace name is "ClassConversion" and it is
a simple console program.
The demo program provided shows simple interfacing between Python and C++. It
in fact, implements a simple python scripting system.
It defines two Python
methods namely "DisplayDayNames()" which displays seven days of a week and
"Distance(x1,y1,x2,y2)" which finds the distance between two coordinates using a
simple mathematical formula.
PyRun_SimpleString("import DemoModule");
PyRun_SimpleString("from DemoModule import *");
PyRun_SimpleString("print Distance(2,3,4,5);");
PyRun_SimpleString("DisplayDayNames();");
The above 4 lines executes Python code line by line using the embedded
interpreter.
Conclusion
This article, by describing the advantages and disadvantages, does not
advocate to use only compiled languages or only interpreted languages. It is
also fully possible to use both. But you've to be very clear which to use where.
For example, if you opt Python for developing an application, you can still use
C++ to speed up the critical parts of your code where speed is necessary. Rather
than using the library provided with Python distribution, one can use Boost.Python
Library to seamlessly interporate the both languages. Download the full Boost distribution which will be useful in all
sorts of development.
More Information
Bibliography
The D Programming Language by Andrei Alexandrescu - Buy
the book
The Dragon Book Principles, Techniques and Tools by Alfred V.
Aho, Monica S. Lam, Ravi Sethi and Jeffrey D. Ullman - Buy the
book
Online Reference
Interpreted Language - go to the page
Compiled Language - go to the page
Managed Code - go to the page
Websites
Boost libraries site - www.boost.org
Python website - www.python.org
D Programming
website - www.dprogramming.com
History