In this Blog article I would like to share some of the dilemmas that we met when creating X#. Especially some dilemmas where we discovered that the VO/Vulcan compiler allowed things that other languages, such as C# and VB, did not allow.
Case 1
CLASS ParentClass
VIRTUAL METHOD OnTest() AS STRING
? 'parent'
RETURN 'parent'
END CLASS
CLASS ChildClass INHERIT ParentClass
METHOD OnTest() AS STRING
? 'child'
RETURN 'child'
END CLASS
FUNCTION Start() AS VOID
LOCAL o AS ParentClass
o:= ChildClass{ }
? o:OnTest()
RETURN
When you compile this code without any "special" compiler options what would you expect ?
In Vulcan this code calls the OnTest method in the ChildClass because it assumes that when the parent method is VIRTUAL then you have probably forgotten the VIRTUAL modifier in the child class, and so it automatically (and silently) makes the child method VIRTUAL as well. Other languages either throw a warning or call the OnTest method on the Parent.
We have chosen to emulate the Vulcan behavior and to make the child method Virtual as well
Case 2:
SEALED CLASS TestClass
VIRTUAL PROPERTY TestProp AS INT
GET
RETURN 0
END GET
END PROPERTY
END CLASS
The SEALED modifier tells the compiler that the class cannot be inherited from, the VIRTUAL modifier tells the compiler that you want to allow the property to be overridden in a subclass. That combination really does not make sense.
Vulcan compiles this code without warnings or errors. Other compilers such as C# generate an error, because their authors probably thought that this is a design error. Also there is a (very small) performance difference between the virtual property and a NON virtual property.
The current version of X# also generates an error, but we have decided to change this and now generate a compiler warning, because we want to let you know that this is maybe not what you intended to do. You can ignore the error but that choice is up to you.
Case 3:
A similar problem is the following:
The SEALED modifier for a method tells the compiler that you do not want to allow further overriding of a method. It is intended for situations like he following:
CLASS ParentClass
VIRTUAL METHOD mmm() AS VOID
END CLASS
CLASS ChildClass INHERIT ParentClass
SEALED VIRTUAL METHOD mmm() AS VOID
END CLASS
In this code you do not allow further overriding of the method in another childclass.
But we found code like the code below:
CLASS TestClass
SEALED METHOD mmm() AS VOID
END CLASS
In this case the SEALED method does not make any sense. Again Vulcan compiled this without errors or warnings, where C# and VB will generate an error (METHOD cannot be sealed because it is not an override).
Just like in the previous example we have decided to generate a warning for this kind of code and not an error.
These were just 3 of the many cases which we found in our own code and the code from our Alpha testers. And of course we all thought we had been writing perfect code before, but our code code contains many of these examples.
You will probably also find similar cases in your code when you recompile with X#.
Does this make X# a bad product or does this make your code bad ?
I would say neither of the two. X# is stricter than Vulcan and helps you to find potential problems in your code.
in my opinion:
in the 1st case, the more clear for the compiler is to generate a warning.
in the 2nd case, I would like the compiler to generate an error.
In the 3rd case, I agree with the warning generation.
regards
George