Section 7: Type annotations
The primary purpose of type annotations are for type checking, so that we can prevent a handful of bugs to be introduced into our program albeit it cannot detect logical errors. Moreover, type annotations can also serve as useful documentations.
Since Keli is a minimal language, type annotations are actually basic expressions in disguise. For example, the type annotation
List.of(Int)is actually a polyfunc invocation.
In Keli, there are 6 places where we can write down type annotations:
- 1.Function parameters
- 2.Function return type
- 3.Object property value type
- 4.Carryful tag carry type
- 5.Lambda parameter
- 6.Type casting
Although a type annotation can be consist of any valid identifiers, the conventions in Keli dictates all type annotations to be written in
PascalCaseexcept for special circumstances.
Built-in types are types that can't or isn't encoded in Keli. For example, integers can actually be encoded as Peano numbers using tagged unions, but due to performance issues we chose to support integer type directly.
Object type annotation can be created using the following grammar:
A valid value for the type annotation above is:
Array type annotation can be created using the following grammar:
A valid value of the type annotation above is:
The type annotation for lambda expression (or functions) can be created using the following grammar:
Type constraint annotation are used in generic functions and generic types. Its purpose is to limit the kind of types that can be passed into specific generic functions and generic types. In Keli, there are 3 kinds of type constraint, namely no constraint, interface constraint or row type constraint.
To specify no constraint, we can use the
Anyidentifier. For example,
(this T).identity | T = this
For example, we can declare a generic function that takes any objects with the property
(this T).isOld | Boolean = this.age.>=(50)
Then, we can pass in object of any shape, as long as it has the property
= $.name("Keli") age(50).isOld // No error
= $.age(20).isOld // No error
= $.job("Programmer") age(40) // No error
= $.name("Pine").isOld // Error, missing property `age(Int)`