Five years later...
Since I'm reviving Extension Types, it brought me face to face with the issue of these old extensions introducing clutter, in terms of built-in symbols that you pay for whether you use them or not.
You can see how the original %words.r
grew between R3-Alpha and R3-Atronix/Saphirion:
R3-Alpha: https://github.com/rebol/rebol/blob/master/src/boot/words.r
R3-Atronix: https://github.com/zsx/r3/blob/atronix/src/boot/words.r
It's messy, and building in the words grows the lookup hash table... costs you the string storage... and costs you the memory Stub corresponding to the string (though small strings fit in the Stub).
So I decided it was time to implement the idea...
A Little Different...
This is what I originally suggested:
#define SYM_OVERLOAD 15092 #define SYM_MULTIPLE 32091 #define SYM_INHERITANCE 63029 void On_Module_Load() { Register_Symbol("overload", SYM_OVERLOAD); Register_Symbol("multiple", SYM_MULTIPLE); Register_Symbol("inheritance", SYM_INHERITANCE); } void On_Module_Shutdown() { Unregister_Symbol(SYM_OVERLOAD); Unregister_Symbol(SYM_MULTIPLE); Unregister_Symbol(SYM_INHERITANCE); }
I've made it a bit easier by having an #include
file with the SYM_XXX defined that you can use in your extension. But I call them EXT_SYM_XXX instead.
Also, what you get back is actually not a Symbol*
, but instead a Value*
.
"Why a Value?".. you ask. Well, because it's not useless to have the value around, and because for now an API handle is the easiest way to prevent the GC from collecting the symbol if it's not used. You don't want that to happen between the Register/Unregister calls, because if it disappeared and came back it wouldn't get the symbol ID.
If there were space inside the symbol to put a reference could we could put it there. But things are hyper optimized, and there's not space for that--for such a fringe feature. Even if the space was available, I'd use it for something else.
So it looks more like this:
Value* g_word_overload = nullptr;
Value* g_word_multiple = nullptr;
Value* g_word_intheritance = nullptr;
void On_Module_Load() {
g_word_overload = Register_Symbol("overload", EXT_SYM_OVERLOAD);
g_word_multiple = Register_Symbol("multiple", EXT_SYM_MULTIPLE);
g_word_inheritance = Register_Symbol("inheritance", EXT_SYM_INHERITANCE);
}
void On_Module_Shutdown() {
Unregister_Symbol(g_word_overload, EXT_SYM_OVERLOAD);
Unregister_Symbol(g_word_multiple, EXT_SYM_MULTIPLE);
Unregister_Symbol(g_word_inheritance, EXT_SYM_INHERITANCE);
}
(You don't technically have to pass the symbol in on unregistering, but it's a sanity check.)
And that's all it takes to be able to use the EXT_SYM_XXX in switch()
statements in your extension... without bloating the core with your weird words!