We introduce generic types. This requires the following tasks:
- functions that take types as an argument and return a type can be implemented and evaluated (the result of such a function call is called a generic type)
- a function call can be used as the type of an instance (i.e. instances of generic types can be created manually)
- functions that take types as an argument and return a function can be implemented and evaluated (the result of such a function call is called a generic function)
- functions created by a function can be evaluated (i.e. generic functions can be called)
- instance validation (i.e. generic functions can be used as validators for generic types,)
- instance validation works (i.e. I cannot store an instance of a generic type that does not pass validation)
- instances of generic types are displayed correctly in the UX
- functions using generic types as their input or output types can be defined and implemented
This goes hand in hand with changing the data-model to the full data model, in particular:
- change Z10/List from a type to a function taking a type
- change Z8/Function from a type to a function taking a list of types and a type
- change Pair to take two types (note that this is currently on Z22, needs to be updated first)
- update Z4K2 to take a list of Z3s, Z4K3 to the proper Z8, Z8K1 to a list of Z17, Z8K2 a list of Z20, Z8K3 a list of Z16, Z12K1 to Z10(Z11), Z22K1 to Z10(Z21), Z50K1 to Z10(Z3)
- the builtin functions need to change their signatures as well
Once the move to Z8 is done, we can significantly tighten the validation of Z7s. Especially, in a composition or function call,
- every argument with a literal should be compatible with that literal
- every argument with a function call should be compatible with the return type of that function call
- every argument with a function reference should be compatible with that function reference