2022/07/28 –, Purple
Inspired by the compile-time features of Zig, we present a CompTime.jl, a package that wraps Julia’s features for generated functions into a seamless interface between compile-time and runtime semantics. The desire for this came from heavy use of @generated functions within Catlab.jl, and we have found that CompTime.jl makes our code more readable, maintainable, and debuggable. We will give a tutorial and then a brief peek into the implementation.
CompTime.jl presents a macro, @ct_enable
, that can be applied to a function, and provides a DSL within the function to mark parts that should be run at compile time, and parts that should be run at runtime. As with @generated
functions, the code run at compile time can only depend on the types of the arguments. However, with this macro, arbitrary control structures (for loops, while loops, if statements, etc.) can be run at compile time and “unrolled”, so that, for instance, only the body of the condition that succeeded in an if statement appears at runtime. Additionally, computation based on types that cannot be itself typechecked very well can be moved to compile time, and what is left to runtime can then be completely type checked, unlocking the power of the Julia compiler to optimize.
This does not present any new technical capabilities beyond what is already provided by generated functions; rather, the chief benefit is the many conveniences enabled by moving all the syntax-processing to general functions. For instance, the code generated for a specific set of argument types can be printed out and inspected, and in backtraces the line numbers associated with the generated code are meaningful, pointing to the correct line in the @ct_enable
-decorated function whether the error happens at runtime or compile time. Thus, the experience of working with generated functions becomes accessible to a Julia user that knows nothing about syntax trees.
Finally, if all of the CompTime annotations are stripped out of a @ct_enable
-decorated function, one is left with a perfectly valid Julia function that runs completely at runtime. Thus, in situations where one expects to run the function only a couple times on each new datatype, the first-compile slowdown can be avoided.
In this talk, we will present a tutorial of how to use CompTime.jl, accessible to a novice Julia programmer with no previous knowledge of generated functions but of interest to all audiences. Then, at the end of the talk, we will take a peek under the hood of CompTime and show the audience a bit of the frightening delight that is writing code that generates code to generate code. This will mainly be as a fun brain-twister; however, the Julia programmer familiar with macro writing may learn a thing or two of interest.
I'm a master's student at Utrecht University, studying probability and thermodynamics, and I also have been contributing to AlgebraicJulia for the last two years.