Add class support
This is not going to be trivial, partially since our current TypeReference
implementation presumes that variables and functions always return a valid CLR type. Well, a class being defined in the global (or local) scope, isn't a CLR type (at least not until we make the move to make all Perlang classes exist as valid CLR types as well - this move will come at some point to make Perlang code interop with existing .NET code properly, being able to implement .NET interfaces by Perlang classes etc), so that's at least one of the challenges. There will probably be numerous others as well.
Here's the Crafting Interpreters chapter about the jlox
implementation of classes: https://craftinginterpreters.com/classes.html. It doesn't help us that much since the static typing support we added in !54 (merged) has made things much more complex. We are already quite different from jlox
and there is unfortunately no-one apart from ourselves that we can ask for help about how things work in our code base...
Initial features (supported in 0.1.0)
-
Calling static
C# methods to support things likeBase64.encode
andBase64.decode
(initially exposed asbase64_encode
andbase64_decode
but moved to class-based static methods in !79 (merged))
Features likely to get implemented, but not as of the initial effort (0.2.0 or "Later")
-
User-defined classes: define classes in Perlang code and be able to instantiate them. - This was started in the 0.1.0 milestone, but the code that existed was removed in !183 (merged). Adding it here for reference. We should put it back, and make it work equally well as in Lox.
-
C#-defined classes: be able to instantiate classes defined in C#. This would be very useful and help us to add nice things like an IntList
(mutableList<int>
, for lack of generics)- We'll need a
new
keyword for this or similar, unless we go the Ruby approach and just tack.new()
after the class name. Making constructors be nothing else than plain static factory methods does have a few advantages, but it makes things likefinal
fields (which must be initialized statically or in the constructor) way harder to achieve.
- We'll need a
-
Inheritance: while this is nice and a fundamental in OOP, this is a "more advanced" feature and might get implemented a bit later. We are not hostile to OOP in any way, so I am not opposing it, just deferring it slightly. -
Visibility: public
,private
,protected
,internal
,protected internal
(similar to package-private in Java, which unfortunately can only be specified by not explicitly giving a visibility. This is one of the design deficiencies of the Java language from my perspective)
Features that are likely to not ever get implemented (i.e. "non-goals")
- Multiple inheritance. While useful sometimes, it can cause the diamond of death problem and in general, increases complexity of a computer system without adding enough value to warrant the cost.
Implementation details
Implemented parts (included in 0.1.0)
-
Be able to define classes (!73 (merged)).Disabled in !183 (merged). -
Detect multiple classes with the same name, throw an exception if this happens (!73 (merged)) -
Support for calling static methods (only on native .NET classes at the moment) (!73 (merged)) -
Support for calling static methods with parameters. (!79 (merged)) -
Support for defining classes in "native" .NET code, and static methods on these. (!79 (merged))
Remaining parts
-
Support for instantiating classes. -
Support for calling methods on instances -
Support for fields and/or properties -
Support for defining static methods -
...probably a bunch of other things as well