When making decisions about whether or not two types are compatible for assignment, Dana considers type equivalence at a structural level and ignores naming. The following two types are therefore compatible in Dana's type system:
data Person {
char name[]
int age
}
data Address {
char streetName[]
int houseNumber
}
Because there is no structural difference between these two types (they both have a character array field followed by an integer field) Dana considers them equivalent and compatible for inter-assignment. The same type compatibility rules apply to interface types.
Under these rules, note that the "packages" in which interfaces appear are treated as a programmer-level semantic annotation that is not relevant to the language in determining compatibility.
Dana does not support an explicit cast operator. However, compatible types can be assigned as part of a regular assignment operation, for example:
String a = new String("Hi")
Data b = a
String c = b
You can query at runtime whether or not a given type has a particular sub-type identity by using the hastype operator. As an example, consider a function that receives an Object instance as a parameter. We can then use hastype to determine whether or not this Object is structurally equivalent to a File type and then call File operations on it:
void function(Object o)
{
if (o hastype File)
{
File f = o
char buf[] = f.read(64)
}
}