Tag Archives: static

No more lies about static fields

When you declare a static field in C# it is not a field per se — it is a tiny getter which initializes the field on first read. I don’t like this approach because it misinforms the user — user wants a direct access but instead she or he gets a wrapper function. Small lie but still a lie. Initializing all static fields eagerly, even unused, is also not a good idea. So I tried to combine those two in a meaningful way…

Static fields can be initialized only with basic values and the initialization is done eagerly (plain old Int static field with initial value 100 is fine). Every other static field is forbidden.

For other types (and complex initial values) properties come to the rescue — properties are initialized lazily with added guards. The message is clear and the safety is guaranteed, in case of circular initialization you will get nice crash (I am not joking, on various occasions I noticed .Net 4.5 keeps working with silently inserted nulls).

Those changes effectively killed static variables so I made temporary exception in sake of testing them — any Int expression is treated as basic value. Another temporary leftovers are static constructors — I am not sure what to do with them, they will be limited to linear initialization or completely removed.

Full solution will take more time — sure bet are lazy types. With lazy types the notion for user is straightforward thus they could be used for all static fields. The other solution could be allowing function and namespace properties.

Advertisement
Tagged , , , , ,

Static inheritance of an interface

The more I dive into implementing Skila the more I appreciate the role of the type system. Yet another interesting case is with generics — how to make them compile-once and be efficient for both complex and native types? Say, you would like to implement “Vector<T>” — one operation which has to be executed is copying the value.

In C++ world you define template and when using it, given type appears viable (or not), however it goes with the price of compilation of each instantiation of the template. In C# you can specify constraint that “T” has to inherit from something like “ICopyable”. But native types do not inherit from anything, so how to make them fit into a template?

I noticed that generics supports object oriented programming, but is not dependent of it. So sure, you can express such constraint, but you can specify another one — making “T” to provide all methods (or extension functions) declared in “ICopyable”.

This makes type such as “Int” fit for “Vector”:

class Vector<T>
  where T : static ICopyable;
...

Note the keyword “static”, “T” is no longer checked against given inheritance, but against providing a set of methods.

The methods are checked when “Vector” is instantiated, if you would like to make the code more explicit specify static inheritance when defining the class:

class Foo : static ICopyable
...

This does not add regular inheritance, instead it enforces the given suite of the methods when defining the class “Foo”, not when calling for “Vector<Foo>”.

Tagged , , ,

9 days as 2 hours

I am in rather bitter mood because I finally did validation of static features in Skila — however instead of 2 hours as I anticipated it took me 9 days. I wish I could say I fainted in the process, but I didn’t — and I feel bad about this.

But no matter how bad the things are there is always a lesson to learn — this experience supports in a way idea expressed by Peter Seibel in his talk “Practical Common Lisp” that the language defines thought.

Here, I was so used to the framework I already had for name resolution that it was obvious I should add a few patches, fix this and that, and I will get working solution. I was absolutely deluded — the right way to achieve solution was a major rework and coming up with completely new name resolver. If I did it right from the beginning I would spent 2-3 days on it with steady progress and no frustration.

Now I need some time to take care of my regular duties, I should be back in 2 weeks.

Tagged ,

All the noise about static

Who would thought that adding “SELF” can cause so much fuss — obviously I needed “static” notion in Skila, which I hadn’t have and when I added it appeared NLT parser is not suitable for new set of parsing rules.

The last problem came as no surprise — so far NLT forking parser executed all user actions, even in multiple branches. This had to lead to problems and hit me this weekend. So instead of doing fancy stuff with pinned constructors, I sat down and changed executing user actions into logging parser actions. On successful parse, all commands are played back and then user actions are executed.

No rocket science, nevertheless I was one day short, and after adding exposing field’s methods feature plus fixing PHP backend a bit I ran out of time. I plan to squeeze error reporting on static misuse into workdays so I will be able to come fresh to implementing pinned constructor and “SELF” next weekend.

Tagged , , , ,

The syntax of accessing static elements

Until now, I didn’t realize how twisted is the history of design of such little feature. In C++ you can access static elements from an instance or a type:

my_obj.InstanceField;
my_obj.StaticField;
MyType::StaticField;

Not bad, but of course Java guys had to simplify things:

my_obj.InstanceField;
my_obj.StaticField;
MyType.StaticField;

C# designers noticed there are too many dots here, and there is too little difference between the first two calls so… they removed external access to type element from an instance. The only options available are:

my_obj.InstanceField;
MyType.StaticField;

And this is the worst choice you could make, because sometimes all you have is an instance (object) and you have to jump through some hoops just to get the type of instance.

Skila brings sanity back:

my_obj.InstanceField;
my_obj::StaticField;
MyType.StaticField;

Such syntax is consistent with accessing namespace elements (Skila borrows it from C#, not C++) and it also improves readability — when you access an element via an instance by looking at next symbol (dot vs. colon) you can say whether it is a type or an instance element. One can think of a dot as the same level access (type to type, instance to instance) while double colon serves as cross level access (instance to type).

Tagged , , ,

Implicit generics and pinned constructors

It is preliminary step of enhanced generics we know from C# and I hope all things finally clicked in for implementing this feature. Consider such code:

public class ClassModifier : TreeNode
{
  public bool IsAbstract { get; private set; }
  public bool IsVirtual { get; private set; }
  public bool IsStatic { get; private set; }

  private ClassModifier(NodeCoords coords)
    : base(coords)
  {
  }

  public static ClassModifier Abstract(NodeCoords coords)
  {
    return new ClassModifier(coords) 
      { IsAbstract = true };
  }
  ...

and

public class MethodModifier : TreeNode
{
  public bool IsAbstract { get; private set; }
  public bool IsVirtual { get; private set; }
  public bool IsStatic { get; private set; }
  public bool IsNew { get; private set; }
  public bool IsOverride { get; private set; }

  private MethodModifier(NodeCoords coords)
    : base(coords)
  {
  }

  public static MethodModifier Abstract(NodeCoords coords)
  {
    return new MethodModifier(coords) 
      { IsAbstract = true };
  }
...

Factory methods as usual, nothing special except the code is highly redundant. In PHP it can be expressed nicely because it has static constructor with late binding — it works like static polymorphism. It can be shortened in C# too, but with ugly twists.

However Skila is meant to be expressive and compiled language.

So I came up with idea of pinned constructor for the beginning. Once added to any class such constructor has to be overridden in every descendant class (or automatically upgraded). Secondly special keyword to express static polymorphism is needed — “SELF” sounds just right. With those two enhancements the code becomes much shorter (it is not Skila yet):

public class ClassModifier : TreeNode
{
  public bool IsAbstract { get; protected set; }
  public bool IsVirtual { get; protected set; }
  public bool IsStatic { get; protected set; }

  protected pinned ClassModifier(NodeCoords coords)
    : base(coords)
  {
  }

  public static SELF Abstract(NodeCoords coords)
  {
    return new SELF(coords) 
      { IsAbstract = true };
  }
  ...

public class MethodModifier : ClassModifier
{
  public bool IsNew { get; private set; }
  public bool IsOverride { get; private set; }
  ...
}

Thanks to pinned constructor it is safe to write “new SELF(coords)” — every class has to support such call. And because “SELF” works as implicit generics when I call “MethodModifier.Abstract()” I will get “MethodModifier”, not “ClassModifier” despite the fact the method is static and it is defined in “ClassModifier” class.

Tagged , , , , , , ,