-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Proposal meta-metaprogramming support #648
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
Comments
I'm not clear on what the usecase is. It looks like you want to implement a build system in zig, which is supported currently with the Also, most of these ideas have serious complexity considerations, like the circular dependencies inherent in |
Also, remember that one of our goals is being friendly to package maintainers, and one goal of package maintainers is reproducible builds. Features which could cause non-deterministic builds such as random numbers and timestamps are problematic. For example, the debian reproducible build project has a pattern for code that wants to have the build timestamp. The upstream project depends on a special macro or allows a configure option to set the build time, and the debian package provides it from a saved timestamp that they create when they import the source tarball. |
@thejoshwolfe: about (4): the aim is to discover (and then present to the user) structure of app's source tree, after the build starts, not to duplicate the build system. A library independent of anything else could use it, and this separation is why I proposed it. The functionality could be certainly added into the builder, but that only makes the thing more complex. I do not think there's anything circular in returned project description, the structure contains strings, numbers a pointers pointing inside. Walking it through is up to the user. Edit: unless the compiler executes compile time code as it goes, before it establishes full knowledge of the source tree. Then this builtin would be impossible. @andrewrk: I have only vague idea who package maintainers are. However, the concern about reproducibility could be handled by command line option which disables all fuzzy constructs (either in release mode or always). Not every application needs to be restricted by this requirement. Of those proposals, the one with highest value for troubleshooting is probably (5) - stack traces. On Windows it is possible to extract detailed stack trace using system APIs from PDB file. (clang, however, failed to produce correct PDBs.) I am under impression that Zig implements its own stack tracing and this could be exposed. |
It's planned to support stack traces on windows. See #516 for the status on PDB. It will be fixed when llvm 6 is released. |
If needed I can provide working code that does Win32 stack tracing (under MSVC). Zig's own implementation would be probably faster, Win32 needs to dig into debug files. |
This is how the compiler works, if i understand you correctly. This is to enable code like Jai solved this problem with 2 comptime execution passes iirc, but Zig is not ready to handle that kind of complexity yet. Our solution to making the compiler into a library may end up being fundamentally different from Jai's. |
Use case for The problem: function with C++ templates suffer this problem. Possible fixes: C++ standard committee tried to handle this problem by adding very complex "concepts" feature to the language. clang lead developer claimed that it is theoretically possible to solve this in current C++, w/o concepts, by walking up template instantiation tree and finding the place where it went wrong for the first time, but nobody does it, AFAIK. Nim has its own "concepts" ( https://nim-lang.org/docs/manual.html#generics-concepts ), but their syntax still feels as overcomplicated. What could Zig do: use existing features - compile time It could look like:
Here the type requirement is that How it could work:
This convinces the compiler that what happened is violation of type parameter requirement. The compiler would then:
Type asserts would also serve as informal documentation for the parameters. |
@thejoshwolfe is correct, JAI allows injection of arbitrary code into already parsed ASTs that are then re-parsed. It also supports message pumping between the still running compiler threads and the build program. @andrewrk and I were discussing it on IRC one day and the thought was this seems to violate zig zen and is more appropriate for Jon Blow's domain. |
This is a strange way to type check, and I don't think it's very safe or intuitive. The only use case I see is to support duck typing, but if you want that you might as well use a different language. |
I propose to add several builtins:
compile time
@currentSourceLastModifyTime() -> u64
: would return seconds since 1.1. 1970 when the current source file was modified last time. Would give the same guarantees astime()
(i.e none - no promise of monotonicity, local timezone). Available only when OS supports such functionality.Use case: there are several files with similar data/functions, this API allows some compile time code to pick up the latest one and use it in runtime. For quick and dirty experiments, w/o need for extra configuration.
compile time
@currentSourceFileName()
,@currentSourceLine()
,@currentSourceFileLine()
: equivalent of__FILE__
,__LINE__
and their combination. The first and especially the last one should return pointer to readonly memory, usable w/o copying. Should be full file name according to OS rules, not something "portable".compile time
@currentFunctionName()
: equivalent of__function__
, available only where applicable. Even if function gets inlined it should give the correct name.compile time full project description:
@currentProjectDetails()
returning complex data structure:This would allow the program to show/store information about its internal structure.
debug mode only: stack trace at given point
@getStackTrace()
: it should return pointer to a string which stays intact during application run, to avoid the need for copying. Each subsequent call (with the same call chain) would return the same pointer. This would allow, for example, to store such pointer in every allocated memory block metadata, to trace the leaks.compile time
@getUniqueRandomNumber() -> u64
: would return nonzero random number unique per whole build. Uniqueness is the key point. Could be used e.g. for serialization keys.Potentially, there could be parameter specifying the range from where these random numbers are generated, to avoid conflicts between different versions of the same application (e.g. if they are used as primary keys in shared database):
@getUniqueRandomNumber(from, to) -> u64
.compile time
@getUniqueId() -> u64
: similar to previous builtin, but generating numbers from 1 up. These could be used as human readable unique identifiers. Similar to__COUNTER__
, but app wide.compile time
@doesThisCompile(any code) -> bool
: would test whether parameter, if it got placed instead of this builtin call, passes OK through syntactical and semantic analysis.run time (and both in debug and release mode)
@isRunningUnderDebugger()
, at least where OS supports this (Win32 does).Builtins (6) and (7) could be probably implemented as user functions, but having them easily available would encourage their use.
The text was updated successfully, but these errors were encountered: