I'm doing it purely for educational purposes right now, but if it turns out good maybe I'll release it. It's very similar to C#, but it just outright drops most of the historical baggage that it brought along from C.
The best example of this is the 'switch' construct in the language, which is something that pisses me off about C#. In C# switch statements you are required to place a 'break' instruction at the end of each case, with the exception of cases with no instructions, which fallthrough into the next case.
Example:
switch (x) {
case 0:
case 1:
int y = 4;
Console.WriteLine ("x is either 0 or 1");
break; // this MUST be here
case 2:
int y = 6; // compile-time error, 'y' already exists in the current scope
Console.WriteLine ("x is 2");
break; // this TOO must be here
}
Yes, even that last break has to be there, supposedly to make sure a developer never adds a case without adding the 'break' between the old last case and the new case. If you think about the logic of that it's pretty retarded, and really is only there to make it look like Microsoft has improved it. As you see with the multiple definitions of 'y', the whole inside of a switch statement is within the scope it is placed in, meaning in order to define similarly-named variables within multiple case statements, you must place {}s around the cases like so:
switch (x) {
case 0:
case 1: {
int y = 4;
Console.WriteLine ("x is either 0 or 1");
break; // this MUST be here
} case 2: {
int y = 6; // compile-time error, 'y' already exists in the current scope
Console.WriteLine ("x is 2");
break; // this TOO must be here
}
}
And boy, doesn't that look retarded. All the current IDEs get confused too when you do this, changing the indent on lots of stuff while you hammer out the curly braces.
So with that said, here's Fera's interpretation of the switch statement.
switch (x) {
case 0:
case 1:
int y = 4;
Console.WriteLine ("x is either 0 or 1");
case 2:
int y = 6;
Console.WriteLine ("x is 2");
}
As you see, each case statement is given it's own variable scope, and a break at the end of each case is implicit. To fallthrough to the next statement, you use the 'continue' construct like so:
switch (x) {
case 0:
case 1:
int y = 4;
Console.WriteLine ("x is either 0 or 1");
continue;
case 2:
int y = 6;
Console.WriteLine ("x is 0, 1, or 2");
}
The 'break' construct works like it does in C# and other languages, using it causes the instruction pointer to exit the whole switch statement, allowing the next instruction to execute.
Another interesting thing about Fera's switch statement is that it's totally dynamic. The compiler is (well, isn't yet but will be) capable of determining the static nature of the case statements for a given switch statement, so using static cases will allow the compiler to turn it into a constant time branch (CTB). But if it can't do that it will just compile it as a simple cascading set of if/else branches.
int x = 3;
int y = 2;
switch (x) {
case y + 1:
case y + 2:
int y = 4;
Console.WriteLine ("x is 1 or 2 more than y");
case 2:
Console.WriteLine ("x is 2");
break; // this TOO must be here
}
Naturally there are times when you want to ensure that the compiler can use static analysis to improve compilation of your switch. For this purpose, Fera provides the 'branch' construct:
branch (x) {
case 0:
case 1:
Console.WriteLine ("x is either 0 or 1");
case y+1: // this causes a compile-time error
Console.WriteLine ("x is 1 more than y");
}
This doesn't guarantee that the construct will compile to a constant time branch any more than C#'s does, but at least it gives the compiler a chance while making sure the programmer doesn't get any fancy ideas and use dynamic expressions for it's cases.
So there's tons more stuff I'm working to implement, but this is a particularly interesting bit which is already mostly implemented. I think I'll post a few more blogs with info about some of the other features, like contract-based design, aspect-oriented programming, advanced language-level features and more.
No comments:
Post a Comment