Saturday, November 6, 2010

Get your ducks in a row: Type System basics

When starting out thinking through what Tangent needed to be, I started with the type system. When I went to implement the thing and ran into issues, they got worked out by starting with the type system.

This isn't exactly a huge surprise. The type system is what prevents a lot of good options when doing component based architecture in gamedev (the original language motivator). There's a not insignificant push to dynamic languages because of problems with static typing. In my experience though, dynamic languages tend to fall down in practice with larger systems and/or more programmers.

That isn't to say there aren't improvements to be had. That is what Tangent aims for: a flexible version of static typing that gets in your way less.

The most straightforward change is to use a Structural Type System. Simply put, if you have the C# types:


public interface SomethingWithName{
    string Name{get;}
}

public class Pirate{
   public string Name{get; set;}
}


In a structural type system, Pirate is an acceptable subtype of SomethingWithName despite not explicitly inheriting from it. This is pretty similar to duck typing found in dynamic languages, but is statically checked. It allows more generic code, since methods can focus on the parts they need, however the object supplies them. The writer doesn't need to know what that is, and the consumer of the method doesn't need to inherit the right interface just to use something that would work fine.

Unless it doesn't. There is certainly the case where a type might meet the criteria for an interface, but not implement the 'spirit' of the interface. You'll then get some happy runtime errors when the generic method does the entirely wrong thing. To avoid some of that (and to help inter-op with other languages) Tangent also provides a mechanism to disable that behavior. In version 1, the keyword goose (read: not duck) was used to tag a type declaration. Types with the goose tag require that a subtype explicitly inherit from it to be considered a sub-type; just like C# and its nominatively typed kin. Unless I hear a better option, goose is likely to remain the keyword.


For next time, we'll go over some of the other features of the type system, as well as our first unpopular compromise.

No comments:

Post a Comment