Nice is a new programming language. It extends the ideas behind object-orientation in order to better support modular programming and static type safety. It also incorporates features from functional programming, and puts into practice state-of-the-art results from academic research. This results in more expressivity, modularity and safety.
Nice detects more errors during compilation than existing object-oriented languages (null pointer accesses, casts exceptions). This means that programs written in Nice never throw the infamous NullPointerException nor ClassCastException. This aspect is developed in more details in this article.
In object-oriented languages, it is possible to add a new class to an existing class hierarchy. In Nice, it is also possible to add methods to existing classes without modifying their source file. This is a special case of multi-methods.
Many repetitive programming tasks can be avoided by using Nice’s advanced features. Ever got bored of writing tons of loops, casts, overloaded methods with default values, anonymous classes, … ?
In addition to traditional object-oriented features, Nice offers:
This is especially useful for containers (lists, hash-tables) and allows for shorter and safer code. Values of primitive type (int, float, …) can be used in polymorphic code, in which case the wrapping and unwrapping is done automatically by the compiler.
Functions can be created and manipulated as first-class expressions, just like in Lisp and ML. This is much lighter than Java’s anonymous classes in many situations, for instance with listeners in a GUI.
They allow methods to be defined outside classes. This means that new methods can be defined on classes that belong to a different package (even in java.*). This allows for a more modular style: you don’t need to pack classes with all possibly useful methods, but you can split them into several packages dealing with different aspects. Development can then happen independently if each package.
Multi-methods also extend usual methods with the possibility to dispatch on every argument, instead of only the receiver class. This article shows why using multi-methods is preferable to applying the Visitor pattern.
This allows in particular methods to return several values.
Optional parameters to methods
Optional parameters have a default value that is used when the parameter is not present in the call. This is much simpler than in Java, where one has to write several versions of the method for each combination of parameters. The names of the arguments can also be specified at the call site, improving readability and making argument order irrelevant.
Contracts and assertions
Contracts can be attached to methods, to better describe their specification and detect illegal uses automatically at runtime, in debug mode. Contracts and assertions can be disabled, in which case they cause no slow down of the running program. Furthermore, they can be used on any version of the JVM, even prior to 1.4.
Integration with Java
The current implementation is tightly integrated with the Java environment, which offers several advantages. The huge amount of Java libraries can be used directly in Nice programs. Libraries can also be written in Nice and called from a Java program. The Nice compiler produces java bytecode, which means Nice programs can be executed on virtually any platform, with any Java Virtual Machine. Or they can be compiled to native programs with a native Java compiler. The compiler is itself written in Java and in Nice. The compiler needs a JVM version 1.2 or higher to run.
Nice is freely available under the GPL. The runtime classes are licensed under the “GPL + linking exception” license, which means that libraries and programs written in Nice can be licensed under any terms.