There are always opportunities for improvement with any language, this section details the planned changes and their introduction to the platform.
2.1. Directives
Directives provide a mechanism for writing and executing functions at compile time. For instance, you may find yourself writing code for accessor functions however, this can cause clutter and potential nightmares in the face of code maintenance. The solution ? Create a directive that will write the code for you. The directive takes a number of arguments and can generate code that can then be passed to the eval keyword. For example:
class modifies Obj {
directive access( ... ) {
array a = arguments();
string code = "class modifies ${Class.name(self)} {";
Array.each( a ) using ( name ) {
if( name isa string ) {
code += "
function set$name( void value ) {
.$name = value;
}
function get$name() {
return .$name;
}";
}
};
code += "}";
eval( code );
}
} The above directive takes one or more string arguments and generates get and set methods for the code. Note the new keyword directive; the keyword allows ferite to flag the function as a valid directive to stop the execution of a wrong function. The second part of directives is how to use them:
class Example {
private number X = 10;
private string foo = "hi";
[access X, foo];
} The above code calls the directive access and passes the names X and foo to it. The directive creates the get/set methods for the class allowing access to the private variables.
There are various uses for this, such as the ability to setup properties within classes and namespaces, build a class based upon an xml specification at runtime, tie a class to a specific database table etc.
Expected arrival: 1.1.0
2.2. Types On Closures
At the moment the parameters being passed into the closure mechanism are not typed, nor can a closure accept multiple arguments. This is going to be changed so that arguments can take a type and have multiple arguments so that the code below becomes valid:
object o = closure( number index ) {
return index;
};
object p = closure( ... ) {
Console.println( arguments() );
}; Expected arrival: 1.1.0
2.3. Type Hinting
For the most part the flexible type system of ferite can be more than enough checking for the average program. There are times though, when it is useful to clamp down a type to very specific guidelines. The solution is type hinting:
array<number> a = [ 1, 2, 3 ];
object<Stream> o = new Stream();
number<1..10> n = 5;
The type hints are in bold. The array example would restrict the contents of the array to only containing numbers, the object example would only allow the variable to point to an object that is a subclass of Stream (including Stream itself), the number example would restrict the number in n to the range 1..10.
The exact type hints that can be used needs to be discussed in more detail.
Expected arrival: 1.5.0
2.4. No More function On constructor or destructor
This simply removes the need to supply the keyword function before the declaration of constructor ordestructor.
Expected arrival: 1.1.0
2.5. Better Exception Handling
The current mechanism for exception handling sucks. It gets the job done but is cumbersome and does not feel part of the language. This is going to change: there will be the introduction of a throw keyword and iferr-fix-else will be modified to allow the optional collection of an error object.
class SpecialError extends Error {
constructor( string error ) {
super( error, 0 );
}
}
function f()
throw new SpecialError( "Random Exception" );
iferr {
f();
} fix ( object e ) {
Console.println( "We got the error: ${e.getErrorString()}" );
} Expected arrival: 1.3.0