Here is an idea…
Serialize a type. You can sorta create types with @Type. They just can’t have any Decls.
I think it would be cool to go a step further and be able to take a type run it through something and convert it into a string and then take that string back into a type.
You could do all kinds of interesting things with this.
For example, send a type over a connection or stored in a database and then it can be unpacked and used.
I don’t expect Functions to be transferred but constants and fields.
But it might be interesting to have the Functions as stubs to fill in with a Fn pointer. You could do RPC with this.
There are some major issues with this. Types are a comptime idea and not runtime. So, it might have to act like a type and not be a type. But we already have concepts similar such as anyopaque.
You can serialize a type into a string right now, pretty does it to pretty-print @typeInfo
calls. If you wanted to turn this back into a type, with a parser and a call to @Type
, you absolutely could. But it probably wouldn’t have the effect you wanted, because types in Zig aren’t purely structural, they have an identity. So for struct or what have you, you would end up with a type of the same ‘form’, but instances of it wouldn’t pass the type system as compatible with the original.
This is the basic problem you’d run into, yes. Types aren’t meaningful at runtime. You can capture various parts of a Type
structs, and save them as constants to do stuff with later, and that can be useful, but ‘do stuff’ doesn’t include using it as a type.
I think if you hacked on this idea for long enough, you might end up with something like a protobuff. That could be really cool though, a Zig-native protobuff which can take advantage of comptime in various ways might turn out to be really great.
So I don’t want to discourage you, just be aware that once it’s compiled, a Zig program has no idea what a type is, and no way to do anything type-related. You’d have to add all that by hand to get the effect you’re going for.
2 Likes
What do you think of the idea of magic methods? I know it might go contrary to Zig’s principles.
I’m really talking about a new type similar to struct. Instead of having it’s own fields and methods, one defines a special function that gets called whenever anything tries to call a function or access a field on that struct like instance. Sorta like the functional equivalent of the switch-else. Basically a default function and default field accessor.
It sounds like what you’re describing is just a dynamic type a-la Python.
In Python any attribute (aka member) access goes through the magic __getattr__
method. Under the hood Python objects contain a dictionary with each attribute name and value as the key value pair of the dictionary.
If you’re interested in how Python does all this stuff you can read the documentation: 3. Data model — Python 3.12.4 documentation
1 Like
That gives alot of good info. Thanks for that.
It is done in many languages,
It seems like this would violate the principle:
There is no hidden control flow, no hidden memory allocations, no preprocessor, and no macros. If Zig code doesn’t look like it’s jumping away to call a function, then it isn’t.
If the question is whether Zig will add support for runtime type reflection, the answer is no. It isn’t that kind of language.
If the question is whether a cool userspace library could be constructed, which uses compile-time reflection, and some sort of reification scheme, to stream and employ known types between programs, that’s a different story, and I would look into protobufs to see what that could look like.
4 Likes
Static typing! Static typing! Static typing rules!
I could imagine a service/program in C/Zig,
that receives a “type” definition from “outside”,
then launches a C/Zig compiler to transform the definition received
into some form of binary executable (dll/exe),
but what next?..
2 Likes
You could have it create a dynamically loaded shared library that uses the type.
But it seems to me that you would have to find a way to use it generically from the main exe as the type wouldn’t be known.
So,
- Get the type over the protocol or wherever. (This could be a zig file)
- Compile that into a shared library
- Dynamically load that shared library
- Generically access the shared library via C-ABI
There is some major security issues that would need to be addressed.
And I wish there was something a bit more elogant than the C-ABI. On my wish list would be something that works similar to what addModule
/addImport
works like. Or at least had Error Unions/Tagged Unions and even simply not having to use *anyopaque for std types.
It could also be launched as a separate process or thread.