-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Allow compile-time fetching of function arguments in higher-order functions #3493
Comments
An alternate approach would be to provide a way to generate code from within comptime blocks.
|
Looking forward, package maintainers will suffer a great deal in the attempt to provide reproducible builds if Zig code can generate Zig code during the compilation phase. Why don't we leverage the build phase for metaprogramming instead? Both package maintainers and Zig programmers get to have their cake and eat it too. In terms of this proposal, your comptime block would be executed as part of the build system. How exactly requires another proposal, but a few ideas spring to mind: A message system that allows for annotating scope blocks or functions with a unique identifier which would be captured and acted on by the build system. JAI has an example of annotating functions with #test which are compiled and executed by its build system. A buildtime {} block that is executed at build time, by the build system, that replaces the block's contents with the results of the block (for now, assuming a string of Zig code, but we shouldn't be so restricted in our thinking in the long term). The code inside these blocks would have access to Zig source metadata, provided by the Build system, and so would not resemble blocks of surrounding code, and would not be recognized by the Zig compiler directly. |
That's a good point. Perhaps code generation from strings is more than is needed here. In a more limited sense, Zig is already capable of generating code at compile-time. Consider this example:
This technique could almost be used to solve my use case:
What I'm really looking for is a way to write the generalized |
A similar problem exists with generic types. Perhaps there is a single solution that solves both cases.
(edit: s/[]/[_]/) |
Ah, looks like the struct case is addressed by #383. |
This is somewhat related to #208, but where that is concerned about function calls where the argument types are known to the caller but not the callee, this proposal concerns the problem of when the argument types are known to the callee but not the caller. |
All sound points. Traditionally, source substitution via Macros was the 'path of least resistance' to address this. Zig does not support Macros, but there is a need to programatically substitute or generate source at some level. I do not know if that means to make Zig more self-aware so that code files have the capacity to somehow modify themselves, or if that task is on us as Zig programmers who know the context of our programs -- to author a Zig program that alters our Zig source. That is why I suggested empowering the build system -- metaprogramming becomes a coherent workflow across the board. It is the natural place to put this power, since a self-authored Zig metaprogram is essentially just a pre-processor for the already existing build system. And that is not a modern advancement from C in many respects. |
I believe this use case is now addressed with @call. |
There are times when it's useful to generate a call to a function whose arguments are known at compile-time, but not explicit in the written type.
Said another way, I'm looking for a compile-time equivalent to JavaScript's apply(). Zig doesn't have variant type arrays, even at compile time, so a direct port is not possible. But having some analogue could be helpful.
As an example, consider the following construct:
It's currently possible to use a struct to work around this, giving us:
This workaround has a few drawbacks:
It would be nice if I could write some sort of inline for over the parameters of the function to specify their values, as I can for a struct.
One potential way to solve this would be to have function types also generate a struct type with the arguments, and supply a macro @apply that takes a function and this struct.
The struct type would be available as
builtin.TypeInfo.Fn.params_struct_type: ?type
. If the function has at least one parameter of type var, no struct can be generated.The names of the fields in the struct are param0, param1, ...
This would allow the first example to be written as:
Of course, in order for this to be able to make the value->pointer optimization, there would need to be restrictions on the use of the struct. There's probably some other formulation that allows for that expression without having arbitrary limits.
The text was updated successfully, but these errors were encountered: