-
Notifications
You must be signed in to change notification settings - Fork 1
Exploration: Generic Types
The proposal in this document is merged.
Generics are an extremely valuable concept that allows a programmer to flexibly build higher-level constructs that are modular and reusable within an application. For example, it is undesirable to create an implementation of a linked list for every possible type of content that can be put into a linked list. Rather, it is better to have a single generic linked list implementation that can be safely reused with any type.
To accomplish this, the current BType type system will be modified. Currently, types are made available by the declaration of a type. Consider the following piece of BType code:
object Foo {
bool bar;
}
var x = new Foo();
When this code is compiled, the declaration of Foo makes that type available for use in the rest of the application. A concrete object shape is defined.
This approach will be abandoned and instead performed in reverse. That is, the declaration of Foo does not create an object shape, it defines the ability for an object with a potentially greater-than-one number of shapes to be created. The shape of Foo is not fully defined until it is used at least one time. Because Foo does not specify anything that would cause its shape to be variable, it can only ever have one shape.
The keyword with will be used to define variable types within an object declaration. It will be immediately followed by an identifier and a semicolon.
object Foo {
with X;
with Y;
# ...
bool bar;
}
These must come before any other items within an object declaration. Attributes may not be declared more than once. The identifier used is bound to the normal restrictions on BType identifiers, but it is suggested that these identifiers start with a capital letter.
These identifiers can then be used in any place within that object where a type would otherwise be used.
object Foo {
with X;
array<X> content;
X first;
new(X first) {
self.content = new array<X>(100);
self.first = first;
self.content[0] = first;
}
X:getFirst() {
return self.first;
}
}
To use an object with variable types, each variable type should be provided as a type attribute:
var x = new Foo<bool, str>();
Type validation logic is significantly complicated by the introduction of these types. This is because objects and their methods and members cannot be type-checked until a usage of the type is encountered. Additionally, type validation must occur for each combination of types that are passed as attributes.