www.digitalmars.com         C & C++   DMDScript  

digitalmars.dip.ideas - Symbol Registration

https://forum.dlang.org/post/zydktpzmvhcpxgeqhzwv forum.dlang.org

On Wednesday, 25 September 2024 at 17:09:04 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 For a long time now (~10 years), I've wanted a cheap way of 
 registering symbols for frameworks to operate on. Existing 
 registration schemes are expensive, and slow. They usually 
 require some effort on the programmer to make happen, not ideal.

 A solution to this can be seen in ``ModuleInfo`` and 
 ``xgetmembers``, have the compiler perform the registration of 
 a symbol transformed into a descriptor list that then can be 
 used to do stuff with at runtime.

 However existing methods are not geared up to be used by a 
 library writer for registration of custom data, this proposal 
 offers a way to do this registration cleanly and effortlessly 
 by the user. So they can focus on their goal rather than the 
 how.

 In this design, UDA's trigger registration of a symbol, but 
 this UDA must first have an attribute specific to the list 
 placed upon it.

 In core.attributes the following mixin template implements the 
 list mechanism.

 ```d
 mixin template ListOfSymbolState(SymbolState, alias 
 SymbolTransformation) {
     private MySymbolState/* ... */ symbolStates;

     enum Attribute;

     ptrdiff_t length();
     int opApply(scope int delegate(immutable ref SymbolState) 
  safe nothrow  nogc)  safe nothrow  nogc;
 }
 ```

 To use it as a library writer:

 ```d
 module library.registration;

  mySymbolStates.Attribute
 struct Route {
     string path;
 }

 mixin ListOfSymbolState!(MySymbolState, MySymbolTransformation) 
 mySymbolStates;

 package(library):

 struct MySymbolState {
     string fqn, name;
 }

 template MySymbolTransformation(alias symbol) {
     enum MySymbolTransformation = 
 MySymbolstate(__traits(fullyQualifiedName, symbol), 
 __traits(identifier, symbol));
 }
 ```

 By the user:

 ```d
 import library.registration;

  Route("/")
 void myRoute() {

 }
 ```

 When the enum ``Attribute`` in ``ListOfSymbolState`` is placed 
 upon a symbol, that symbol when used as a UDA will trigger 
 registration.

 Registration is done on a symbol, that is then transformed 
 using ``SymbolTransformation`` a template, that results in a 
 value of ``SymbolState`` which must be a struct.

 A ``SymbolState`` is stored in a list ``symbolStates`` that 
 external code does not have direct access to.

 The list is compiler and linker defined sequence of elements. 
 Common strategies for this are linked lists and section 
 appending. Due to the possibility of moving by the loader, no 
 interior pointers are allowed in ``SymbolState`` or to an 
 element.

 Exportation of the list is compiler and platform defined, 
 assume that it is not exported, and each binary must be 
 registered separately. See dub's ``injectSourceFiles`` 
 directive for how to do this.

 This will enable deserialization, orm's, web routes, game 
 logic, GUI controls, to self register.
That's a really interesting problem! I can definitely see the need for a simpler, faster registration method. The current approaches can be quite cumbersome and add unnecessary overhead, especially when you're dealing with a large number of symbols. It makes me wonder, has anyone explored leveraging a hash-based system for quicker symbol identification? Thinking about it, it almost feels like the kind of optimization puzzle you might enjoy while taking a break playing something like [Drift Hunters](https://drifthunters3d.io) – something challenging but ultimately satisfying to solve! Good luck with your search!
Dec 06