In this post:
- Changing plans, cutting ideas
- A grab-bag of desired features
- Applications I have in mind
Another late Friday post...
On further reflection, it's a bad idea to attempt an "everything is an object" system in Lua without creating an entire runtime to deal with it. As such, I'm going to restrict the scope of the current idea/project to dealing with wrapped values, basically putting forward composition as much as possible. There are two special cases I want to account for in my current ideas on accmplishing this stuff. One is that ideally there should be a fast path for objects that wrap a single value. The other is that it should be possible to create singleton objects that don't have a constructor or track internal state. It'd also be nice to memoize the wrapping functionality. I'll see how far I can get without parametric types, but I'll probably be thinking about introducing them, we'll see.
So, I'm currently focused on generic wrapping, which means I'll relax the "everything is an object" stuff at least enough to mitigate the need for specific boxed types.
Here's what I have in mind for all of this stuff:
- All objects are empty tables with the same metatable.
- objects are constructed by calling types, which are objects that wrap a table and optionally a constructor.
- types with no constructor are singletons, and are considered to be instances of themselves (unless this doesn't work)
- "methods" are vanilla functions that take two arguments from the system machinery: one that is just the self object, and one that is the accessor function for the wrapped values; there's a utility function that converts this into filling in a fixed number of wrapped values.
- Wait, that means I probably can't do the "fast path" thing, oh well.
- The constructor takes no extra arguments, and returns values to be wrapped.
- It is an error for a method to return a mutable wrapped value.
- Tables, functions, threads, and userdata are assumed to be mutable; booleans, strings and numbers are known not to be.
- Can't wrap nil I guess.
After the values are returned from the constructor and wrapped up, the wrapped value and the type are associated with the new object.
Let's look at the kind of stuff I want to prototype with this whole idea:
- Wrapped values representing absolute positions, relative positions, and scaling factors
- Wrapped values representing dimensioned quantities
- Wrapped values representing oriented quantities
- Wrapped values representing vectors and matrices
Basically, I want to prototype some of the stuff I've been trying to do in Rust, and try actually applying it to something before trying to optimize.
Next time, I'll try to get the basics of all of this working.