I have made a lot of progress on the design of the runtime, and the features I want.
But we’re still nowhere near something “stable”. I met some roadblocks which makes me rethink the semantics and the syntax as a consequence.
In my opinion, the syntax needs to reflect clearly the semantics of the language. The syntax is “derived” from the semantics.
In this article, I’ll expose some of the roadblocks I’ve met and what solution I have thought of.
Quick Recap: The type system
The type system of Letlang is dynamic and enforced at runtime. This is because of the very nature of what a “type” is in Letlang.
For a quick reminder: Values do not have a type, instead they belong to a collection, called a “class” (inspired from proper classes in set theory). The class defines the constraints a value must respect to be considered “part of the class”.
The example I like to give is with the classes
even: all integers
n % 2 = 0
odd: all integers
n is not even
In the runtime, classes are modelled as functions that takes a value and returns a boolean indicating whether or not it belongs to the type.
This model prevents static type checking. When checking types during compile-time, I need to be able to verify the “compatibility” between types, consider the following classes:
mod2: all integers
n % 2 = 0
mod3: all integers
n % 3 = 0
mod4: all integers
n % 4 = 0
Here, we can say that all members of
mod4 are also members of
mod2. But we can’t say the same for
mod3. This means:
mod4is compatible with
mod3is not compatible with
mod2is not compatible with
mod4(not all multiples of 2 are multiples of 4)