Type Declaration
Tags: programming, languages
Published: 2024-01-19 07:43:04

Introducing new keyword `type` for anything which goes into type table for either type-checking or type inference.

## Record Types
There will be `record` for data structure declaration.
Therefore:
```dart
type point = record {
  var x : float;
  var y : float;
}
```

Also developers can define operator functions using condition statements:

```dart
type point = record {
  var x : float;
  var y : float;

  == => function(other:point) : bool {
    return (x == other.x) && (y == other.y);
  }

  [] => function(index:int) : float {
    return branch {
      index == 0 => return x;
      index == 1 => return y;
      otherwise => return float.NaN;
    }
  }

  [] => function(index:int, value:float) : void {
    branch {
      index == 0 => x = value;
      index == 1 => y = value;
      otherwise => nop;
    }
  }
}
```

So therefore a check like:
```dart
var p1 : point = {
  x = 1;
  y = 2;
}

var p2 : point = {
  x = 2;
  y = 2;
}

printf("%b\n", p1 == p2); // false
printf("%b\n", p1 < p2); // error: operation type(point) < type(point) is not implemented.
```

### Generic Records
A generic record can be defined like this:

```dart
type tpoint = record : T1, T2 {
  var x : T1;
  var y : T2;
}

var p : tpoint<int, int> = {
  x = 1;
  y = 2;
}

var p2 : tpoint<string, string> = {
  x = "12";
  y = "13";
}
```

### Record Functions
Functions can be included in a record with `field`, anything which does not need setting when introducing a record can be defined as `field`.

```dart
type point = record {
  var x : Float;
  var y : Float;

  field distance = function(other:point) : float {
    var dx = x - other.x;
    var dy = y - other.y;
    return math.sqrt( dx*dx + dy*dy );
  }
}

var p1 : point = {
  x = 2;
  y = 3;
}

var p2 : point = {
  x = 5;
  y = 6;
}

p1.distance(p2); // 4.24264
```

-----

## Enum Types
So enumeration types are the same as any enumeration type yet they can have underlaying type.

```dart
type invalidation_flag = enum : int {
  Text = 1;
  Color = 2;
  Size = 4;
  All = Text | Color | Size;
}

var flag1 : invalidation_flag = 1; // Valid
var flag2 : invalidation_flag = Color; // Valid
var flag3 : invalidation_flag = flag1 | flag2; // Valid
flag3 == 3; // true
var flag4 : int = All; // Invalid: All is not of type int
```

By default enums inherit `int` types and start from 0.

------

## Union Types

Union type can only accept one of the underlaying types and it's size is the biggest value inside the union declaration.

```dart
type some_type = record {
  var x : int;
}

type number = union {
  var x : int;
  var y : float;
  var z : double;
  var n : some_type;
}

var a : number.x = 12;
var b : number.y = 0.2;
var c : number.z = 0.2;

0.2 == b; // true
c == b; // false
c.x; // 0 : double -> int conversion
a.z; // 12.0: int -> double conversion
a.n; // throw error: no viable conversion between int -> some_type.
```

-----
## Function Type

We can have function types when binding to a variable:
```dart
var x = function(a:int, b:int):double {
  return double(a + b);
}
```
type of x is now a function with underlaying type of:
`int->int->double`

```dart
type ftype = function (int, int) : double;
var m = function(a:ftype, d:double):double {
  return a(1, 2) + d;
}

// type of m : ftype->double->double

m(x, 3); // 6.0 
```