package ppx_const
Install
Dune Dependency
Authors
Maintainers
Sources
md5=312df50473157aa8677506437180a496
sha512=b9ee4c3cb85277b60c4fe4aedae75e50cdefdc8b1e822f5ad0774a6cee25d1c866c3387379344c5eba7f80c883727e803973451b1f99290bf0edc05e7cdffe5f
Description
This is a ppx extension which adds if#const
and match#const
constructs to
OCaml. They behave like normal if
and match
, but conditions are evaluated
at compile time and AST sections not selected are excluded from the program
completely. In conjunction with ppx_getenv, this can be used for conditional
compilation of code.
README
ppx_const
This is an OCaml language extension implementing if%const
and match%const
statements. The if%const
and match%const
are evaluated at compile time, and the appropriate clause substituted without the ignored clause(s) being fully compiled. This allows you to avoid consequences such as module inclusion or type inference changes which would otherwise have resulted from the ignored clause(s).
In other words, ppx_const works like #if
in the C preprocessor, but is implemented entirely within the OCaml language using the ppx mechanism. In conjunction with ppx_getenv, this provides a lightweight alternative to Cppo.
This software was written by Andi McClure <andi.m.mcclure@gmail.com>, based on whitequark's ppx_getenv sample. Significant upgrades were contributed by Kate Deplaix.
Because ppx_const is based on ppx, it requires OCaml 4.02 or newer.
Usage
ppx_const may be invoked with either if%const
or match%const
.
if%const
if%const
may be invoked with either of:
if%const COND then A else B
if%const COND then A
COND must be one of the following:
true
false
An expression consisting of two literals (strings, ints, floats) and either the
<>
or=
operator.
COND may also contain extension nodes (including if%const
s) as long as they evaluate to a constant expression by the time ppx_const sees them.
A and B are not required to be of the same type. Like with normal if
, the return type of if%const false then X
is unit.
match%const
ppx_const can also be invoked with the following:
match%const MATCHED with P\_1 -> E\_1 | ... | P\_n -> E\_n
MATCHED and P_1..P_n must be either literals (strings, ints, floats) or one of the special constructors true
and false
. Like with if%const
, MATCHED may contain extension nodes, although the P1..P_n may not.
The patterns P_1..P_n may also be variables or _
, in which case they will always match. Matching on a variable name will "bind" a variable by that name in the match expression: If a pattern P_i is a variable x
then the expression, if matched, will compile to let x = MATCHED in E_i
.
An example: Using ppx_const with ppx_gentenv
Say your program has a Graph module with heavyweight dependencies (cairo or whatever). Some users may prefer to compile your program without the graph feature, so that they don't have to install the dependencies. You can do this by installing ppx_const and ppx_getenv, and invoking the graph feature like this:
if%const [%getenv "BUILD_OMIT_GRAPH"] = "" then
Graph.create filename
else
print_endline "Graph feature not available."
In this example, when you build, if the BUILD_OMIT_GRAPH
environment variable is set to a nonempty string then the Graph.create
call will be omitted entirely from the compiled binary. If this is the only invocation of Graph, then the Graph module and all its dependencies will also be omitted from the binary. If you do not set this environment variable, the [%getenv
check will become an empty string at build time and the graph function will be included.
OCamlbuild users take note: For this example to work, you'll need to make certain that ppx_getenv runs before ppx_const, so that if%const
sees a constant string and not the [%
node. If you are using Dune, then Dune will take care of this for you. In OCamlbuild, you set a load order by ordering the packages like this in your _tags
file:
<*>: package(ppx_getenv, ppx_const)
License
Creative Commons Zero ("public domain or equivalent")