prep is a small Go tool that enables compile-time function evaluation. By using prep.Comptime, you can evaluate functions at build time, replacing them with their computed results. Just like comptime from Zig. Except it's not.
- Compile-Time Evaluation: Replace function calls with their computed results at build time.
- Simple Integration: Use
prepas both a Go library and a standalone executable. - Tooling Support: Easily integrate
prepwith your Go build process using-toolexec.
To use prep in your build process, install it as a binary executable:
go install github.com/pijng/prep/cmd/prep@latestTo use the prep library in your Go project, add it via Go modules:
go get github.com/pijng/prep
go mod tidyTo mark a function for compile-time evaluation, wrap it with prep.Comptime:
package main
import (
"fmt"
"github.com/pijng/prep"
)
func main() {
// This will be evaluated at compile-time
result := prep.Comptime(fibonacci(300))
fmt.Println("Result:", result)
}
func fibonacci(n int) int {
fmt.Printf("calculating fibonacci for %d\n", n)
if n <= 1 {
return n
}
a, b := 0, 1
for i := 2; i <= n; i++ {
a, b = b, a+b
}
return b
}After wrapping your functions with prep.Comptime, you need to use prep during the build process. This is done by using the -toolexec flag:
go build -a -toolexec="prep <absolute/path/to/project>" main.goThis command will evaluate all functions wrapped with prep.Comptime and replace them with their computed results during the build.
Important:
-aflag is required to recompile all your project, otherwise go compiler might do nothing and use cached build<absolute/path/to/project>is and absolute path to the root of your project. If you rungo buildfrom the root of the project – simply specify$PWDas an argument.
./mainNote the speed and absence of calculating fibonacci for %d message.
Basic Literals Only
Currently, prep.Comptime only supports basic literals as arguments. Which means you can either:
- Pass a basic literal directly like this:
func job() {
prep.Comptime(myFunc(1))
}- Use a variable with the value of basic literal from the same scope as wrapped function:
func job() {
x := 1
y := 2
prep.Comptime(myFunc(x, y))
}Compile-Time Evaluation
Only functions that can be fully resolved with the provided literal arguments can be evaluated at compile-time, therefore it is impossible to use any values from IO operations.
Because reasons.