Introducing Clump

Clump is an object oriented language allowing object, interface and finally class creation. But the understanding of the language basis is required. For this purpose this tutorial first describes these basis in order to be able to build later solutions where entities like objects, interfaces and classes are required.

This is the traditional hello, world! Clump program.

class helloWorld(System) implements Main {
    start(args) {
        this.stdout().println("Hello, world!");
    }
}
	
Compiling this code is done easily calling the compiler.
shalla-bal:clump $
./bin/clumpc helloworld.vor -o site/bin No [-t <target,...>] option specified. Generating code for Java only.
shalla-bal:clump $
./bin/clump helloWorld -l site/bin Hello, world!
shalla-bal:clump $
In this example helloWorld is a class, Main an interface and finally main(...){ } is a method. Therefore such class provides a set of behaviors to an entity denoted by the keyword this; Such entity can also be called an object if you wish even if this is not the exact word) of type System. Like Java such kind of objects provides basic mechanisms like providing the standard output calling this.stdout().

Interface for Main program entry definition
package clump.lang

interface Main {
    void start(String[]);
}
      

Like imperative language three basic flow controls exist: The sequence, the loop and finally the branching flow control. We presents each of these flow control and the existing syntatic variations.

Sequence

class sequence(System) implements Main {
    start(args) {
        this.stdout().print("Hello, ");    // Statement 1
        this.stdout().println("world!");   // Statement 2
    }
}
	  

Loop

class loopWhile(System) implements Main {
    start(args) {
        int i = 0;
        while(i < args.length()) { 
            this.stdout().println("Hello, "+args[i]+"!");           
            i += 1;
        }
    }
}
	  
shalla-bal:clump $
./bin/clump loopWhile -l site/bin Bob Alice Hello, Bob! Hello, Alice!
shalla-bal:clump $
This sample code can be written using for(...) statement.
class loopFor(System) implements Main {
    start(args) {
        for(int i = 0; i < args.length(); i += 1) { 
            this.stdout().println("Hello, "+args[i]+"!");           
        }
    }
}
	  
class loopIntegerIter(System) implements Main {
    start(args) {
        for(int i : args.length) { 
            this.stdout().println("Hello, "+args[i]+"!");           
        }
    }
}
	  
class loopStringIter(System) implements Main {
    start(args) {
        for(String arg : args) { 
            this.stdout().println("Hello, "+ arg +"!");           
        }
    }
}
	  

Branching

The branching flow control specifies a condition to be verified or not. Based the condition result a statement is executed. Therefore such statement expose statements to be executed depending on the condition value.

class branching(System) implements Main {
    start(args) {
        if (args.length() == 0) { 
            this.stdout().println("Hello, world!");
        } else {
            this.stdout().println("Hello, "+args[0]+"!");           
        }
    }
}
	  
Then the execution of the code depends on the passed arguments as shown in the next session.
shalla-bal:clump $
./bin/clump branching -l site/bin Hello, world!
shalla-bal:clump $
./bin/clump branching -l site/bin Alice Hello, Alice!

Optional else statement

The else statement can be optional.

class branchingOpt(System) implements Main {
    start(args) {
        if (args.length() == 0) { 
            this.stdout().println("usage: ....");
            this.exit(1);
        }
    }
}
	  

Unless statement

When the condition must not be verified the negation can be used. Nevertheless the flow control can be expressed with the unless statement.

class branchingOpt(System) implements Main {
    start(args) {
        unless (args.length() != 0) { 
            this.stdout().println("usage: ....");
            this.exit(1);
        }
    }
}
	  
In both cases the execution without parameters has the same result.
shalla-bal:clump $
./bin/clump branchingOpt -l site/bin usage: ....
shalla-bal:clump $

In Clump the expression null is not an instrinsic value but an explicit one. Therefore all variable in Clump must be initialized and null value is allowed only if the type allow it. For this purpose an initial object Null is proposed and the Nullable type is build on top.

Definitions for null denotation and management
package clump.lang

object final Null {}

type Nullable<E> = Null | E

Null null = new Null()

E getFromNullable<E>(Nullable<E> n) {
    // Omitted code ...
}

boolean isNull(Nullable<void> n) {
    // Omitted code ...
}
	  
Such nullable values implies a strong type definition where nullable must be specified. For example a String variable which can be null must be specified as Nullable<String>. This is illustrated in the next example.
class nullableString(System) implements Main {
    start(args) {
        Nullable<String> variable = null;

        if (args.size() != 0) {
            variable = args[0];
        }

	if (isNull(variable)) {
	    this.stdout().println("value is null");
	} else {
	    String value = getFromNullable<String>(variable);
	    this.stdout().println("value is " + value);
	}
    }
}
shalla-bal:clump $
./bin/clump -l site/bin nullableString Value is null
shalla-bal:clump $
./bin/clump -l site/bin nullableString Alice Valus is Alice

An array is an indexed structure containing entities with a same type.

Interface for an Array
package clump.lang

import clump.util

interface Array<E> extends Iterable<E> {
    int size();
    E getAt(int) throws IndexOutOfBoundException;
    E[] subContent(int, int) throws IndexOutOfBoundException;
    void setAt(int,E) throws IndexOutOfBoundException;
    E[] clone();
}
	    
A common way to create and manipulate an array is to use syntactic constructions. Then new int[10](0) creates an array of size 100 and a default value set to 0. Accessing is the classical expression integers[2].
class arrays(System) implements Main {
    start(args) {
        int[] integers = new int[10](0);
        for(int i = 1; i < 10; i += 1) {
            integers[i] = integers[i-1] + i;
        }
        for(int element : integers) { // Iteration
            this.stdout().print(element.toString() + " ");
        }
        this.stdout().println();
    }
}
	  
shalla-bal:clump $
./bin/clump array -l site/bin 0 1 3 6 10 15 21 28 36 45
shalla-bal:clump $
In fact all these expressions are macros in Clump. The genuine syntax was given by the next code source. where macros are in fact replaced by the basic statements and expressions.
class arrays(System) implements Main {
    start(args) {
        Array<int> integers = array.create<int>(10,0);
        for(int i = 1; i < 10; i += 1) {
            integers.setAt(i,integers.getAt(i-1) + i);
        }
        // ...
    }
}
	  

Multi-dimensional Array

Indeed an array can contain another one but object is not a conventional two-dimension matrix because each array entry can refers another array with different dimensions. For example triangular two-dimension arrays can be built as proposed in the next example.

class multiArrays(System) implements Main {
    start(args) {
        int[][] multi = new int[][10](new int[0](0));
        for(int i : multi.size()) {
            multi[i] = new int[i+1](i);
        }
        for(int[] line : multi) {           
            for(int element : line) {
                this.stdout().print(element.toString() + " ");
            }
            this.stdout().println();
        }

    }
}
	  
Then the execution of the previous sample code display a triangular structure.
shalla-bal:clump $
./bin/clump multiArrays -l site/bin 0 1 1 2 2 2 3 3 3 3 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9
shalla-bal:clump $
The expression new int[][3](new int[5](0); create an array where 3 entries and each entry refers the same array of 5 entries and not a different one for each. Then v[2][2] = 2 modifies all entries implying v[0][2] == v[1][2] == v[2][2] == 2.