codon/docs/language/statics.md

1.8 KiB

Sometimes, certain values or conditions need to be known at compile time. For example, the bit width N of an integer type Int[N], or the size M of a static array __array__[int](M) need to be compile time constants.

To accomodate this, Codon uses static values, i.e. values that are known and can be operated on at compile time. Static[T] represents a static value of type T. Currently, T can only be int or str.

For example, we can parameterize the bit width of an integer type as follows:

N: Static[int] = 32

a = Int[N](10)      # 32-bit integer 10
b = Int[2 * N](20)  # 64-bit integer 20

All of the standard arithmetic operations can be applied to static integers to produce new static integers.

Statics can also be passed to the codon compiler via the -D flag, as in -DN=32.

Classes can also be parameterized by statics:

class MyInt[N: Static[int]]:
    n: Int[N]

x = MyInt[16](i16(42))

Static evaluation

In certain cases a program might need to check a particular type and perform different actions based on it. For example:

def flatten(x):
    if isinstance(x, list):
        for a in x:
            flatten(a)
    else:
        print(x)

flatten([[1,2,3], [], [4, 5], [6]])

Standard static typing on this program would be problematic since, if x is an int, it would not be iterable and hence would produce an error on for a in x. Codon solves this problem by evaluating certain conditions at compile time, such as isinstance(x, list), and avoiding type checking blocks that it knows will never be reached. In fact, this program works and flattens the argument list.

Static evaluation works with plain static types as well as general types used in conjunction with type, isinstance or hasattr.