Support multiple programming paradigmsZimbu does not enforce one specific style of programming. You can do it they way that works best for the task at hand. Procedural, like C: define procedures and data structures separately. Object Oriented, like Java: define classes that hold both procedures and data, support inheritance and other mechanisms to encourage code re-use. Functional: support function references, closures and callbacks. Less punctuationMany C-style languages contain a lot of punctuation. Not only is it easy to get this wrong, it also obscures the core of the code.
int myfunc(int a, int b) {
int result = 0;
for (int i = a; i <= b; ++i) {
result += i;
}
return result;
}
Zimbu does away with most punctuation:
FUNC myfunc(int a, int b) int
int result = 0
FOR i IN a TO b
result += i
}
RETURN result
}
Using } to end a block without a { to start it is a trademark of Zimbu. Perhaps it would be more logical to use END, but it turns out that using } makes the code easier to read.
Zimbu encourages using one statement per line. In special cases, e.g., a long list of similar lines, Zimbu allows using a semicolon to separate two statements:
CASE 4; a = 3; b = 6
CASE 5; a = 4; b = 8
Type inferenceIn Java you often see a line like this:
SomeClass<SomeType> foo = new SomeClass<SomeType>();
Having to specify the type twice is bad. Zimbu has two ways of doing this:
SomeClass<SomeType> foo = NEW()
VAR foo = SomeClass<SomeType>.NEW()
The first way is preferred, declaring the type of var and instantiating an object of that type.
The second way is more suited for when the object is created in another way, where you do not need to know the type, e.g.:
VAR foo = Foo.createFromBar(bar)
When using VAR the type of the variable will be set at the first assignment. All use after that must match that type. To have a variable that can be any type, with runtime type checking, use ANY (this has not been implemented yet).Easy to readPrograms are read many times more often than written. And it must be easy to spot mistakes. For example in large numbers:
n = 1'000'000'000
m = 0x12a'f3e7'3b34
x = 0.000'000'01
ImportsWhen using functionality from standard Zimbu libraries there is no need to import anything. The compiler knows where the libraries are.
Some languages have the problem that you never know what you get from an import. Especially in C and C++ it is possible to break a working program by adding an item in a header file.
In Zimbu an import defines exactly one symbol and it matches the file name:
IMPORT Hello.zu # Defines Hello and nothing else
IMPORT new/Hello.zu AS NewHello # Imports Hello as NewHello
Compiler pluginsQuite often you don't write code manually, but generate it from a template or an interface specification. Or you want to import an image file into your code as a literal. Zimbu supports this which plugins. For example, to use Google protocol buffers: IMPORT.PROTO zui.proto The proto plugin will read the "zui.proto" file and generate classes for the protocol messages it defines. These classes can then easily be used in the Zimbu code. You can write your own plugins and extend the compiler in a flexible way.
ClarityIn most Object Oriented languages a class name can be used as a type that can also be a child object of that class. What this actually means is that the variable can store an object that implements the interface of the class. In Zimbu it is possible to really say that a variable can only be an object of a class and not a child class.
CLASS Animal # Also defines Animal.I, the interface of Animal
...
} CLASS Fish EXTENDS Animal # Automatically implements Animal.I
...
Animal.C a = NEW() # a can only be an instance of Animal, not Fish. } Fish f = NEW()
Animal ai = f # ai can be any object that implements Animal.I
a = f # Error! A Fish is not an Animal, it's a kind of Animal
The .I can be added to any class, thus it is easy to create a class that implements the interface of any other class, without specifically defining an interface for it.
} |
Home >