I'm trying something a little different today by writing this up earlier, so I have fewer excuses to stay up at night, because my sleep was just... so messed up. Anyway, I completed the multiline comment challenge, after a few hiccups.
So, next up is "Representing code", and it's actually a good thing I'm trying to write this earlier in the day, because I'm going to need to think about how I implement this stuff this time.
That's because this chapter talks about different programming paradigms and ways of laying out classes, and how to bridge gaps between different styles, and let's see how what I'm doing kind of messes with all of that...
I'm implementing as little as possible when it comes to "object-oriented features". Currently, the way I'm writing "classes" in my code doesn't handle any reuse. The point is more to avoid downstream consumers of an object needing to explicitly require a module to get at basic operations on that object. Another potential motivation that would get me to write something would be if I had polymorphism; that is, if multiple kinds of object implemented the same operation in different ways However, that's not what I'd use for what Robert Nystrom is using the visitor pattern for, for exactly the reason that he's using the visitor pattern.
The other issue here is that Lua doesn't do static type-checks (unless something really fancy came out when I wasn't looking), and missing fields just resolve to nil, so my best hope there is to error out as early as possible.
Thinking about these problems, a solution begins to take shape:
- "classes" somehow involves a callable constructor, which creates "instances", and somehow provides access to the __index table for the type of the instances.
- These constructors can use the contracts code I wrote earlier.
- Those contracts can be defined inline using a function factory that takes a key name as input.
- The "visitors" should be Python-style protocol functions like len. They should be defined unlike how Python does them. Instead, they should mostly use a table associating the constructor callable to the implementation for the instances of that callable.
- Just realized the __index-like table should be an ephemeron table, which is no big deal.
The big thing I need to work out before I start writing code is, what kind of callable should the constructors be, and how it should relate to the __index table (which need not actually hook into the metatable system in that way).
Anyway, I'll ponder that for a while, and try to take things easy for the rest of the day.