Generating a map at compile time?

Update: The suggestions to use Marshal, ppx_blob, and custom dune rules to achieve this seem very well placed. The build is very transparent, and the payoff in terms of runtime does seem to be quite significant. Even things like printing the help text end up loading this module, so it was expensive even in the least useful of cases beforehand.

There definitely are some pain points:

  • I needed to do a good bit of refactoring to move just the code that generates this table into an executable. Especially since it is essentially one big implementation detail, it wasn’t factored very well in terms of its dependencies on the library it was living in in my project.
  • This also provoked me to move both the generating code and the place that holds the result into a new folder/dune library compared to its previous location. Unfortunately, code you want shared between these two needs to live somewhere else, due to dune’s prohibition on a module appearing in both a library and executable in the folder it lives in. If anyone knows why that’s the case, I’d love to hear it.
  • As noted above, Marshal and cores Hashtbl don’t mix, so the thing I’m actually storing is an associative list. Presumably that is leaving some performance on the table as it must be converted at startup, not just un-Marshaled
  • I’m concerned about the mental overhead this adds for new or unfamiliar developers. In particular, things like “go-to definition” take you to the [%blob ...] line, which doesn’t help all that much

So, a far cry from the ideal of “some magic annotation or macro that just tells my value to become compile time”, or something like gprof, but not too bad!

I’m still interested in hearing alternative ideas if people have any. If I end up actually going down this path for implementation, I’ll include my fully worked example as a link in this post at some point

1 Like