civboot / civlua

self contained software to build a minimalist dev environment.
http://civboot.org
The Unlicense
40 stars 0 forks source link

Generics and Fns: I'm doing them wrong #1

Closed vitiral closed 1 year ago

vitiral commented 1 year ago

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.

vitiral commented 1 year ago

No, no generics. #2