Like many object-oriented languages, Grace will have classes. Like some object-oriented languages, Grace will have types. Like a few
object-oriented languages, Grace programmers have the option to ignore classes and use only objects, or to ignore static types and use only dynamic types.
The relationships between objects and classes, and static and dynamic types, are well known. So, then, what’s the relationship between
classes and types in Grace? Or rather, what should be the relationship between classes and (static types?
Here’s the problem. Let’s take a simple Grace class:
|
class Cat { colour', name' -> def color : Colour = colour' def name : String = name' var miceEaten := 0 } |
This class creates a factory object that supports the creation of new Cat instances in response to the method request “new(aColour,aName)” (cognoscenti will notice we’re trying “def x =” syntax to define constants rather than “const x :=”. Sorry Niklaus).
|
def fergus = Cat.new("tabby", "Fergus Trouble") |
What type does the variable “fergus” have? As in C#, local type inference gives it whatever type the “Cat.new” method returns. What if we want to declare that type explicitly, say for a variable?
Here the name “Cat” is being used as a type, rather than a factory. The key question is: where did that type come from? There seem to be two options in the design here:
- The Cat class declaration implicitly creates a Cat type.
- The Cat type must be declared explicitly, separate from the class
declaration:
|
type Cat = { colour () -> Colour name() -> String miceEaten() -> Number miceEaten:=(Number) -> Void } |
The first option, a class implicitly creating a type, is what most typed object-oriented languaes do: a class declaration also creates a type (technically the cone type rooted at the class). Implicit class-types lead to more concise programs, and allow “static typing early” courses to have students write and use their own classes without requiring an explicit concept or separate declaration of a static type.
On the other hand, the second option, explicit type declarations, make static types much more explicit. Under this option, Grace programmers couldn’t declare an explicitly typed variable (or more likely, any method, as method arguments are not inferred) without an explicit declaration of the Cat type. But this clarity comes at a price: simple programs are longer, requiring apparently redundant type declarations, declarations that are close to class declarations, but duplicated some information with some mandatory tweaks.
Grace programmers can avoid the price of a separate declaration in a couple of ways. First they can use dynamic types or local type inference — omitting types from variable and constant definitions will find types via local inference (if the type-checker is run) while omitting types from method arguments and results are interpreted as type dynamic. So the costs of declarations (presumably) would only be required whenever a type is to be written explicitly. Still, this is another case where a ”better” program (with explicit types) is longer and more redundant than a ”worse” program (without them). Most Grace programmers may choose to omit the declarations, so the language would fall into being dynamically typed by default.
In fact, the real situation is worse than this: there are about five or six kinds of “class-like” or “type-like” objects in Grace: a good solution here should address all these roles:
If these are played by different objects — how many different namespaces will Grace need to name them all? If they are accessible in a shared namespace, how are names resolved?
Finally, following C#, Grace will provide constructs to reify the declared static type of an expression (perhaps “decltype(e)”) and the exact dynamic type of an object (“o.dyntype”, or perhaps alternatively “reflect(o).dyntype” via a mirror). The aim here is to let programmers write programs that interrogate the static and dynamic types in their programs. And, whatever the relationship we end up with, do we need better names for static type and dynamic type?