The Essence of Programming Languages

Gaurav Verma Programming Languages Leave a Comment

A number of developers have asked me which programming language I should learn and with this question coming over and over again would hopefully help answer this question.

A programming language is a formal language that specifies a set of instructions that can be used to produce various kinds of outputs for a given computer machine. It should be noted that a computer machine is not necessarily digital or even a real hardware, it may be an abstract theoretical machine like a turing machine. A formal language is defined as a set of strings along with symbols and rules. The upcoming statement may have different opinions with different authors however the author chooses to define classification of languages as follows.

There have been two approaches to define programming languages imperative approach (which includes structured, scripting languages and  object oriented programming) and declarative approach (which includes functional and logic programming). This provides the basis of this discussion.

The two approaches vary by a fundamental process of thought while the imperative block essentially exposes underlying hardware as a programmable machine. The declarative approach being more mathematical describes logic of computation without giving exact steps.

The imperative approach allows control over machine and describing each step. Machine language, Assembly languages and High level language provide increasing degree of abstraction but all expose similar operations of looping, conditional checks, control flows and more.

Declarative languages describe what users want without going deep into how the same shall be achieved for example SQL or a language like prolog.

Let us look at an example of factorial to explain this concept to solve factorial

Imperative Approach Declarative Approach
Int fact =1;

if(input = 0){
fact = 1;
}

else{

for(int i = 1;i<=input;i++){

fact = fact*i;

}

}

fact(0) = 1;

fact(n) = n * fact(n-1);

 

While the above example shows that Imperative approach generates bigger code and requires exact steps, imperative approach builds code that is easier to comprehend, this may not be visible from previous example the next code will clearly show how easy it is to comprehend a code in declarative approach.

Let us look at the example of quick sort (and I should warn that I had to copy the quicksort code in imperative approach because it is not obvious. Further it will be demonstrated that quicksort in declarative approach will also expose the essence of quicksort.

 

Imperative Approach Declarative Approach
int partition (int arr[], int low, int high)

{

int pivot = arr[high];    // pivot

int i = (low – 1);  // Index of smaller element

 

for (int j = low; j <= high- 1; j++)

{

// If current element is smaller than or

// equal to pivot

if (arr[j] <= pivot)

{

i++;    // increment index of smaller element

swap(&arr[i], &arr[j]);

}

}

swap(&arr[i + 1], &arr[high]);

return (i + 1);

}

 

void quickSort(int arr[], int low, int high)

{

if (low < high)

{

/* pi is partitioning index, arr[p] is now

at right place */

int pi = partition(arr, low, high);

 

// Separately sort elements before

// partition and after partition

quickSort(arr, low, pi – 1);

quickSort(arr, pi + 1, high);

}

}

Quicksort (x) = x

Quicksort (x:xs) =Lesser(xs,x) :: x :: Greater (xs,x)

Lesser (y:ys,x) = y<x ? y::Lesser(ys,x)

Greater (y:ys,x) = y>x ? y::Greater(ys,x)

 

The essence of quicksort is given a list of elements take the first element and let that be x. From the remaining list find all elements lesser than x and call it less and take all elements greater than x and call it great. Now merger

quicksort(less), x and quicksort(great)

Assuming a list [5,3,8,7,1,2]

If we apply quicksort to this, the first step will be

5

Lesser[3,8,7,1,2] = [3,1,2]

Greater[3,8,7,1,2] = [8,7]

And we merge

Quicksort [3,1,2] :: [5] :: Quicksort [8,7]

This as we can see will lead to sorting.

However the point being made is that a declarative syntax is easier to comprehend. There are other benefits of declarative languages such as no side effects, they are more scalable and etc.

This brings the question why use use an imperative language and while the author is biased towards declarative languages, the primary benefit is that it is closer to hardware allowing more optimized implementation. There exist more developers who have learnt this style in university. Further computational requirements of such languages has been large which till late was not possible in commercial applications, it is only now that hardware is available to run such systems commercially.

Now that we have a grasp of programming language classes, let us further sub device these in interest of defining various language types which will bring us to the initial questions we posed what programming languages should I learn. We will not focus on assembly and machine language as they are not used unless a specialised application warrants the same.

Imperative languages can be subdivided into Procedural (such as C, Pascal etc.) and Object Oriented Languages (such as C++, Java etc.). Scripting languages (such as perl) are also basically procedural it is there execution mechanism that is different.

Declarative languages may be divided into Functional (such as Haskell or Lisp), Logic Programming (such as prolog), database query language (such as SQL).

It should be noted that each language type exposes programmer to a different style and mindset and perhaps for an overall development a programmer should learn one language of each style.

With our question answered let us get back to discuss the programming language types.

Procedural languages

A procedural language is closest to the metal. It essentially provides hardware independent subset of a language that may be compiled and executed on any machine. They provide high level abstraction over a machines instruction set

Object Oriented Languages / Domain Specific Languages

These are essentially work on a modelling principle and simulate real world domains and business. This allows building up on ideas and combining them.

Functional Languages

A functional language is a programming language that supports functional style, such languages define a program as a set of mathematical expressions. Such languages do not have an global variables or stores hence do not have side effects or mutations.

Logic Programming

Logic programming is a style of programming that allows definition of facts and then derivation of theorems or postulates based on given facts.

Database Query Languages

Database query languages allow a declarative syntax to find information from underlying data stores.

 

Modern programming languages are now following a hybrid approach, Languages such as C# and Java have recently added Lambda expressions, these in turn have provided with quite a bit of dynamic structures and programming.

Declarative languages provide a playground to test language features such as currying, closures which then make to mainstream languages such as java script and others.

Finally we would like to say Declarative languages are here to stay, they already have started to make an impact and it would be wise to start investing in these platforms to gain business benefits.

About the Author

Gaurav Verma

With over 16 years of experience, Gaurav has worked on immensely complex projects in a wide gamut of industries & technologies, having worked with organizations like Sapient & Grapecity among others. A graduate from the Delhi University and Indraprasth University with degrees in electronics and computers, he is currently fascinated by & working on projects involving AI and Machine Learning.

Share this Post

Popular Right Now

Leave a Reply

Your email address will not be published. Required fields are marked *