xtype (halted)

Check-in [69eb7d673b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add hindsight about the project.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 69eb7d673b172ca0757dc2154a894fc744449018f758e91a7a5bd7524d214cb1
User & Date: imagic 2025-01-23 00:36:22.149
References
2025-01-23
00:41 Closed ticket [f46cdab35e]: Write hindsight document. plus 4 other changes ... (artifact: ece946fd58 user: imagic)
Context
2025-08-26
18:41
Rename `ldm` to `ldf`. ... (Leaf check-in: 8e2d3432b0 user: imagic tags: trunk)
2025-01-23
00:36
Add hindsight about the project. ... (check-in: 69eb7d673b user: imagic tags: trunk)
2024-10-06
15:06
Update dev rockspec. ... (check-in: 85f9d87c4c user: imagic tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to README.md.
11
12
13
14
15
16
17









18
19
20
21
22
23
24
- Interoperability: Having a general low-level type system library can ease the
  interactions of third-party code.
- Metaprogramming / Genericity: Exploit the dynamic nature of Lua to generate
  definitions on-the-fly.

Moreover, the `xtype.class` submodule implements a class system based on
**xtype**. See the dedicated [documentation](doc/class.md).










See `src/`, `rockspecs/` or
[luarocks](https://luarocks.org/modules/imagicthecat-0a6b669a3a/xtype).

## Concepts

### Type







>
>
>
>
>
>
>
>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
- Interoperability: Having a general low-level type system library can ease the
  interactions of third-party code.
- Metaprogramming / Genericity: Exploit the dynamic nature of Lua to generate
  definitions on-the-fly.

Moreover, the `xtype.class` submodule implements a class system based on
**xtype**. See the dedicated [documentation](doc/class.md).

----

## Project Status

This project is no longer in development (I am not using it). This
[document](doc/hindsight.md) explains why.

----

See `src/`, `rockspecs/` or
[luarocks](https://luarocks.org/modules/imagicthecat-0a6b669a3a/xtype).

## Concepts

### Type
Added doc/hindsight.md.




















































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# Hindsight

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](fossils:/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 [ldm](fossils:/ldm) 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](https://github.com/LuaJIT/LuaJIT/issues/1268)).

As an example, here is a simple class/mixins system that I use:

```lua
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(...)`