Vikrant

0 - I have created new universe out of nothing, come have a look at it!

Language orientied programming

The best way to write programs is to write a programming language and then start programming in that language.

If anybody thinks it is too much of effort and this statement is just an exaggeration, then I would like to disprove these thoughts in this post. My experience says that this sentence forms a basic philosophy needed to write good programs.

Computer languages are made for computers not for human beings. So it is obvious that if one tries to read the code to understand the program, it will be a tedious job. Same tediousness and difficulty comes into picture if a programmer has to explain the understood algorithm (the understanding happens in human language) to a computer (which is going to be in computer language). Going back to first case, by our good luck,the programmer has written documentation in the code which explains the algorithm in plain human language. Then suddenly the task of understanding the code becomes very easy. What about the second case? How can we ease the task of translating algorithm from human language to computer language? One easiest way is to have a automated translator. But Human languages are too fuzzy to translate automatically. So we can not translate human languages directly to computer language. The way to do it is to choose a language which is mid way to human and computer. i.e Domain Specific Language.

Human language ->Domain specific language -> computer oriented language

Let give me some example from linear algebra. In a human language an iterative algorithm to find biggest eigen value and corresponding eigen vector of a positive definite matrix is as follows.

  • take a random nonzero vector x.
  • Keep pre-multiplying it with the matrix A till you find that every iteration is causing just length change in x by a contact factor e.
  • e is the eigen desired eigen value and normalized from of vector x is corresponding eigen vector.

Lets write a program for this in a java/c like main stream language! oops so much of code to write!

public float[] getRandomVector(int n){
    float[] vector = new float[n];

    for(int i=0; i<n; i++)
        vector[i] = getRandomNumber();

    return vector;
}

public float[] multiply(float[][] matrix, float[] vector){
    int n = vector.length;
    float[] x = new float[n];//all entries are zero by default

    for(int i=0; i<n; i++){
        for(int j=0; j<n; j++){
            x[i] = x[i] + matrix[i][j]*vector[j]
                }
    }

    return x;
}

public float getLength(float[] vector){
    float sum = 0;
    int n = vector.length;

    for(int i=0; i<n; i++)
        sum = sum + vector[i]*vector[i];

    return Math.sqrt(sum);
}

public float[] normalize(float[] vector){
    float length = getLength(vector);

    for(int i=0; i<vector.length; i++)
        vector[i] = vector[i]/length;

    return vector;
}


public bool notConverged(float oldv, flow newv){
    float EPSILON = 1e-7;

    return Math.abs(newv-oldv)/newv > EPSILON;
}

public float eigen(float[][] matrix){
    int n = matrix.length; //assumption is matrix is square!

    float v_old;
    float[] v = getRandomVector(n);
    v_old = v;
    float eigenValue_old = 0.0f;
    float eigenValue = 1.0;

    while(notConverged(eigenValue_old, eigenValue)){
        v_old = v;
        v = multiply(matrix, v);
        eigenValue_old = eigenValue;
        eigenValue = getLength(v)/getLength(v_old);
    }

    return eigenValue;
}

Now let us say we have a matrix language which looks like mathematician's conventional linear algebraic equations. The algorithm in that language will look like as follows

def not_converged(e, e_old):
   return abs(e-e_old)/e > 1e-7

def length(x):
   return sqrt(x'x)

def eigen(A):
   n = size(A)
   x = random(n)
   x_old = zeros(n)
   e_old = 0.0
   e = 1.0

   while not_converged(e_old, e):
      x_old = x
      x = Ax
      e_old = e
      e = length(old_x)/length(x)
   return  e

Can you see the difference? algorithms are same but only key is many things are abstracted out in the martix language. For example matrix multiplication, looping over vector, transpose, dot product all these are not implicitly done by the language! These abstractions will make the algorithm look like matrix algorithm and not like a code in computer language.

A good DSL will make following good things to your code

  • Abstract out domain related basic computations in the form of language.
  • Make the code modular. This will depend on how well your DSL abstractions are done and how well DSL allows gluing of basic primitives provided.
  • Make the code small and understandable, maintainable.
  • Time required for development reduces drastically.