Blogroll

Misc

Contractive and Uninhabited Types in Whiley

By Dave, on April 21st, 2016

An interesting feature of Whiley is that it supports true recursive types. These are surprisingly tricky to get right, and recently we came across some interesting examples that the Whiley compiler should (but doesn’t) check for.

Recursive Types

The type {any data, LinkedList next} indicates a record with two fields data and next, whilst null | Link indicates a union of null and Link. So, a LinkedList is either null or a record of type {any data, LinkedList next}. A simple function operating over LinkedLists is given as follows:

This returns the number of links in the list. The runtime type test operator, is, distinguishes the two cases. Since Whiley employs flow typing, variable list is automatically retyped to {any data, LinkedList next} on the false branch.

Subtyping

With this in mind, let us now think about subtyping between recursive types in Whiley:

In languages with lazy evaluation (like Haskell) such a type would be pretty reasonable. However, in Whiley, all values are trees of finite height — so it is physically impossible construct an value of type InfList. So, the compiler should report an error in such case.

Conclusion

Recursive types are pretty tricky to implement and get right. The implementation in the Whiley compiler is now almost four years old, and it generally works pretty well. But, the compiler isn’t currently checking for types which are uninhabitable (see issue #631 raised for this). Still work to do then …

2 comments to Contractive and Uninhabited Types in Whiley

Hi Dave, Not sure you should check for Uninhabitable types,
I have the feeling that they can be needed in conjunction with genericity (not sure how you do that in whiley),
for example your infinite list is a generic instantiation of a reasonable type
type StuffAndMore is {T stuff, int more}

Well, what you’re saying is that we need to think carefully about how to check for uninhabited types in the presence of generics. That is a fair point actually, and something I hadn’t considered. But it doesn’t mean we shouldn’t check them in general. It could be, for example, that we just produce a warning, etc.