Throw away the current implementation. I did it to solve the problem of type-checking functions at runtime, hence the need for an anchor which had a concrete type. It turns out this is BS: we shouldn't do it. Function type checking is something for a type-checked language. Metaty should stick to records and generic records.
The basic API is something like:
-- A table that has a default key for it's get method
local DT = record'DefaultTable'
:generic('K', Any)
:generic('A', Any)
:field('defaultKey', g'K')
:field('data', Table{K=g'K', V=g'A'}) -- note: changed variable name
:done()
DT.__index = function(self, k)
return self.data[k or self.defaultKey]
end
-- Note: further calls to the same types will return the same instance
local T_SN = Table{K='string', V='number'}
local DT_SN = DefaultTable{K='string', A='number'}
-- passes type checking
local d1 = DT_SN{defaultKey='default', data=T_SN{default=4, other=7}}
-- will fail type checking on BOTH the DT defaultKey and the Table
local d2 = DT_SN{defaultKey=4, data=T_SN{default='foo', other='bar'}}
Basic approach
When a generic is instantiated (i.e. local T_SN = Table{K='string', V='number'}) it sets a "source of truth" for the name mapping and goes through all the fields of the generic to replace the types.
The resulting type itself can still be generic if any of the genvars are still generic, i.e.
:field('data', Table{K=g'K', V=g'A'}) -- note: changed variable name
The resulting table type is still generic except the constraint on the table's V is now g'A' instead of it's previous value of Any. We also need to check that the constraints on the parent type were valid for our constraints (probably need to pass the constraints through or something).
The point is that at the end we have a concrete type if none of the params were generic or a generic type if any of them were generic. The concrete type will have a concrete constructor, whereas the generic type will still have a generic constructor.
Throw away the current implementation. I did it to solve the problem of type-checking functions at runtime, hence the need for an
anchor
which had a concrete type. It turns out this is BS: we shouldn't do it. Function type checking is something for a type-checked language. Metaty should stick to records and generic records.The basic API is something like:
Basic approach
When a generic is instantiated (i.e.
local T_SN = Table{K='string', V='number'}
) it sets a "source of truth" for the name mapping and goes through all the fields of the generic to replace the types.The resulting type itself can still be generic if any of the genvars are still generic, i.e.
The resulting table type is still generic except the constraint on the table's
V
is nowg'A'
instead of it's previous value ofAny
. We also need to check that the constraints on the parent type were valid for our constraints (probably need to pass the constraints through or something).The point is that at the end we have a concrete type if none of the params were generic or a generic type if any of them were generic. The concrete type will have a concrete constructor, whereas the generic type will still have a generic constructor.