In hindsight, and thinking about how to simplify my methodology, I decided to stop using and developing this project.
The first issue is the over-generalization. I wanted xtype to be some kind of standard to increase interoperability between modules. With time, I realized that trying to create a standard is a nice theoretical exercise, but in practice not for me. It requires to federate, to find a consensus, to build something that pleases everyone, or more likely displeases the least amount of people. More importantly, it probably requires some amount of power or luck to make it a reality.
I don't look for those things, to say the least, and I realized that this is why I love Lua, it adapts more to me and my needs. As an example, it seems that people are bashing Lua because it doesn't match the general expectations that people have about programming languages. In addition, it seems that people in the Lua community love to build their own things. They are unlikely to use xtype. I also believe that if a more powerful type system must exist, it should be part of the language.
Another issue is the idea of global types instead of context specific types. People would make all kind of types and modules, and xtype would be the mean to interact with each of them in a standard way. This implies that xtype should specify all of the possible behaviors and relations of objects so they can be understood globally, instead of a contextual semantic, defined by where and by whom the objects are used. I like the idea, but I don't consider it suited for Lua.
Even if I am fine being the only one using xtype, explicit type checking is seldom used in my current projects and multifunctions are used in only one. xtype was created to support the genericity of mgl, but I now want to remove that feature to reduce complexity.
Which brings me to the benefits of not using xtype, which avoids an external and complicated abstraction, and instead to directly use metatables.
It is more idiomatic, it plays on the strengths of the language. Coming from bits of C++, I reused some patterns like enums and OOP; xtype is in line with that. They are artifacts and not necessarily a good fit with Lua.
It is also more interoperable, ironically, because metatables are fundamental to
the language. It keeps things simple to understand and compose. I noticed this
while working on ldf and the metatables dictionnary. There is
conceptual simplification in just using getmetatable to get the type, to peek
at methods, metamethods or metadata without the need to think about an external
dependency.
Especially, instead of being limited to mixins and types, metatables can be used in other ways. Learning to use metatables fluently allows to build abstractions customized to specific applications or problems.
Performance-wise, even if not a priority by default, writing more idiomatic Lua code has probably more chance to yield benefits from the VM and compiler optimizations (see this LuaJIT issue).
As an example, here is a simple class/mixins system that I use:
local function instantiate(mt, ...)
local o = setmetatable({}, mt)
if o.init then o:init(...) end
return o
end
local function is(self, class) return self[class] ~= nil end
function class(...)
local mt = {}
local n = select("#", ...)
local mixins = {...}
for i=1,n do
for k,v in pairs(mixins[i]) do mt[k] = v end
end
mt[mt] = true
mt.__index = mt
mt.is = is
setmetatable(mt, {__call = instantiate})
return mt
end
- Terminal type:
getmetatable(o) - Inherited type checking:
o:is(t)o[t] - Methods and metamethods are defined on the class object in the same manner (with "inheritance").
- Constructor method:
o:init(...)