"Extension Types" Implementation

Due to the type system being a mess and needing rethinking, I had taken all of the extension type implementations (IMAGE!, GOB!, STRUCT! etc.) out of the main repository and moved them into their own GitHub projects.

(I'd wanted to do that anyway--because I wanted separate issue trackers for each extension, distinct from the core.)

Then I ripped out the first attempt at extension types because it was very messy.

But now we have a big advancement, in terms of a unified model of Generic Dispatch which uses the same methodology to dispatch things like COMPARE, MAKE, MOLD, and everything else. This uniformity makes it easier to make an extension type conform to the interface, because there's only one interface to conform to.

So I'm starting to return to putting the implementation in.

One thing I'm doing differently this time is I'm making a special choice of the HEART_BYTE() value to indicate custom types.

I'm using zero.

Why is it important to use zero? Well, because I have a C++ class for encoding optionality, like std::optional (or Rust's Option, or Haskell's Maybe). This class protects you at compile-time from trying to pass optional things to places that expect the thing to be there.

But in order to compile to C, the state used has to be C's idea of "falsey" when not under the C++ rules. That means null pointers or 0 values.

It's hard to stress how important it is when dealing with a feature like this to get good solid checking on when you are dealing with an extension type and when you aren't. You also need protections, like a protection against comparison:

if (Type_Of(cell1) == Type_Of(cell2))
    return "They're equal types!";  // ...OR NOT, if distinct extension types!

When you are comparing two bytes and one of the bytes encodes "it's custom, and you have to look elsewhere in the cell for the specific extension type", then you need to stop that kind of code from being written at compile-time. C++ can do this by deleting the overload when optional types try to compare:

#if CHECK_OPTIONAL_TYPEMACRO
    bool operator==(Option(Type)& a, Option(Type)& b) = delete;
    bool operator!=(Option(Type)& a, Option(Type)& b) = delete;
#endif

So what's neat is that in the C build, Option(Type) is a macro that just turns into Type. And you can test it for falseyness, with the code working just the same...without the compile-time checks.

It might sound like a small thing to change the byte to be 0 for extension types, but it makes a tremendous difference for problems that I was seeing in the code when it was a TYPE_CUSTOM that you had to remember to check for. This gives a big leg up.

Anyway, while the IMAGE! and VECTOR! and FFI! code are all fairly messy and outdated at this point, it would be nice to bring them back into the fold just to show that the system can be extended. So I'm working with IMAGE! at the moment as a first extension type to bring back.

1 Like