Introducting Umana

Here is the initial sketch for a new programming language, umana. I know, I know: the world has already enough programming languages, and it seems to be every programmer’s wet dream to create a new one and join Guido van Rossum and Dennis Ritchie in the Halls of Eternal Fame.

umana, though, is a little different. It doesn’t want to be the proof of great intelligence and technical acumen. Instead, it aims to translate the way computers do things into terms readily understood by humans. Hence the name: while it sounds derived from an African language (think Ubuntu), it is actually the Italian word for, “human.” The analogy here is the term, lingua franca, or Frankish language (in Italian), which was what people used around the Mediterranean to speak to each other when they had no better language in common.

Let me give you an example of how umana translates. Take a class definition from Java:

public class Triangle extends Object {

private Point corners[3];

public Triangle(Point x1, Point x2, Point x3) {

corners[0] = x1;

corners[1] = x2;

corners[2] = x3;

}

}

This is clearly rudimentary. All it does is define a class that stores the three corners of a triangle. It doesn’t actually do anything with the corners, but it will suffice as an example.

If you wanted to express in simple terms what the definition above does, you’d say: “a triangle is an object with three corners.”

That’s almost exactly what the code in umana looks like. The human-readable sentence contains everything a computer needs to know in a clear and concise fashion. There is the introduction of a class “a soandso is a parent” followed by the initialiser, “with three corners.” At this point, umana doesn’t know what a corner might be. We could either provide a definition, “a corner is a point,” or a qualifier, “… with three points called corners.”

umana doesn’t try to map everything programming languages do, and the more esoteric constructs are simply ignored, regardless of how efficient they may be. umana simply assumes that efficiency and speed are secondary, while comprehension (by humans) is paramount. There will never be an umana equivalent of the standard C for loop, for instance, because the idea of the for loop is itself odd.

umana also wants to abstract storage, caching, and other goodies that programming languages strangely don’t do by default, but that typically belong into everything worth programming. Scalability should be a feature of any language, not of frameworks built on top of it. Access to databases, sockets, etc. should be a given – and they are in umana.

Let’s look at some programming constructs. The first one that comes to mind is the procedure. In umana, that’s called an action, and it’s introduced by the standard language construct for a verb. If you want to rotate a triangle by a variable amount of degrees around the origin, in Java you would add the method:

public rotate(float degrees) {

for (int i = 0; i < 3; i++) {

double c = cos(degrees);

double s = sin(degrees);

double x = corners[i].x;

double y = corners[i].y;

corners[i].x = x * c - y * s;

corners[i].y = x * s + y * c;

}

}

You could have spared yourself the temporary variables for the sine and cosine, but not those for x and y, since you are changing the values.

In umana, that looks different:

a point is an object with numbers x and y called coordinates.

to rotate a point by an angle means to replace its coordinates as such: x = x * cos(angle) – y * sin(angle); y = x * sin(angle) + y * cos (angle)

to rotate a triangle means to rotate its points

Of course, if you don’t like mathematical notation, you could replace x = x * cos(angle) with the new x is x times the cosine of the angle.

Notice here how human ways of thinking come into play. When we defined the rotation of the triangle, we did not say that we need an angle. That’s because the definition of the rotation of a point needs that. When you try to rotate a triangle without specifying an angle, umana will tell you that it needs one. And it knows it needs one, because when it will use the definition of rotation of a triangle, it will encounter the rotation of the point, which needs an angle.

This is, of course, the type of late binding that drives computer language type Js (see MBTI) nuts. It is a typical feature of human thinking: conceptualize in generals, and drill down to specifics only when you need to. A Java programmer would know she need an angle at the time she wrote the code – very useful. An umana programmer would have no idea until the computer complains about the missing angle – how sad.

At the same time, the kind of predictive code that type Js like also has the annoying feature of being completely unreadable. If you want to write safe code in Java, you have to sprinkle defensive statements (conditions and exceptions) everywhere. In the end, it’s completely unclear what the code does, because the vast majority of the code is written to deal with the ifs and oopses.

Languages like Java acknowledge that need for readability in indirect fashion. For instance, Java code is required to catch declared exceptions, but not default ones. Any method call on an object will potentially cause a NullPointerException, but to make code readable, this exception doesn’t have to be handled (a leading cause of major blunders in Java code).

For instance, if we instantiated the triangle we are rotating with null points and then tried to rotate, Java would kill our code with just such a NullPointerException. We could modify the rotation code above in one of three ways: (a) we could catch the exception and do nothing.

public rotate(float degrees) {

try {

for (int i = 0; i < 3; i++) {

double c = cos(degrees);

double s = sin(degrees);

double x = corners[i].x;

double y = corners[i].y;

corners[i].x = x * c - y * s;

corners[i].y = x * s + y * c;

}

catch (NullPointerException npe) {

}

}

or (b) we could put conditions around the accessors.

public rotate(float degrees) {

for (int i = 0; i < 3; i++) {

double c = cos(degrees);

double s = sin(degrees);

double x = corners[i].x;

double y = corners[i].y;

if (corners[i] != null) {

corners[i].x = x * c - y * s;

corners[i].y = x * s + y * c;

}

}

}

or (c) we could have the caller deal with it.

public rotate(float degrees) throws NullPointerException {

for (int i = 0; i < 3; i++) {

...

}

}

The problem with this way of doing things is that it’s not the way humans think. We deal with problems when they arise, and the way we note the potential for problems is by adding notes. In this particular case, a null Point is not a valid Point, and this should be noted in the class definition. More in general, umana likes to deal with error conditions and exceptions outside of code paths. This restricts your ability to deal with problems at the point where they arise, but since it makes the code much easier to understand, it’s a feature, not a bug.

Which gets us to the main point of umana: it is a programming language for people that don’t have a formal programming background. Its constructs are such that a person with a basic understanding of what computers do can read umana code and know what it is trying to do. Also, that same person should be able to modify umana code successfully. 

umana is not a natural language processor. It does not try to understand what you are typing, and as such it wouldn’t be suited for the grounds up development of a software application (by a novice). But given sample code or a demo, a tinkerer should be able to figure out how to modify the code to make it do things it hasn’t done before.

Add a Comment

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