Type system

WARNING: Type system is not fully implemented yet. It's more of a kind of annotation. You won't get analysis errors from them currently.

Type as a value

Type is a top class value in Hetu, it can be assigned and returned.

To use a type value in a normal expression, you have to lead it with a type keyword.

fun checkType(t) {
  when(t) {
    type {} -> {
      print('a structural type')
    }
    // the function won't match here
    // you have to use the exact type value here for match
    type ()->any -> {
      print('a function type')
    }
  }
}

Type declaration

You can assign a type value to a name with type declaration.

Type declaration is similar to a variable declaration, except it must has a initializer type expression.

class Person {}

type PType = Person
type FuncTypedef = (str) -> num
type StructTypedef = {
  name: str,
  age: num,
}

There are 4 kinds of type values:

builtin type

Some types are builtin keyword and has special use:

any

This is the equivalent keyword to Dart's dynamic, to indicate that this type can be assign with anything.

void, never & unknown are also builtin keyword, they are part of static type checker, and they are not fully implemented for now.

nominal type

All class names can be used in a type value expression.

class Person {}

structural type

Structural type are a kind of duck typing systemopen in new window. It is used with struct.

It's syntax like the struct literal, however, you have to write types rather than a expression value after the key:

type StructTypedef = {
  name: str;
  age: num;
};

function type

Function types are a kind of type value expression that consists of a parameter type brackets and a return value.

Unlike normal function declarations, You cannot omit any part in the function type expression.

It should have a pair of brackets, a single arrow and a return type.

type FuncTypedef = (str) -> num

Use is to check a type in run-time

Use is to do a run-time type check. The expression after is will be parsed into a valid type value, and you don't need to use type keyword after is.

fun doSomething(value) {
  if (value is str) {
    print('A String!')
  } else if (value is num) {
    print('A Number!')
  } else {
    print('Unknown type!')
  }
}

Use typeof to get a type in run-time

Use typeof keyword to dynamically get the runtime type of a value.

fun main {
  // decalre a function type
  type FuncTypedef = fun(str) -> num
  // assign a function to a value of a certain function type
  var numparse: FuncTypedef = fun(value: str) -> num { return num.parse(value) }
  // get a value's runtime type and return it from a function
  var getType = fun { return typeof numparse }
  var FuncTypedef2 = getType()
  // use this new type
  var strlength: FuncTypedef2 = fun(value: str) -> num { return value.length }
  // expected output: 11
  print(strlength('hello world'))
}

The type of a type is always 'type', no matter it's a primitive, instance, or function type.

type Functype = () -> any
print(typeof functype) // type
Last Updated:
Contributors: 邵燃, chengfubeiming, hythloday@live.com