What Moritz wrote (and you accepted).
But I feel like cooking up an analogy.
how can we formulate this correctly to explain it in the documentation?
Possibly with an analogy. Here's one off the top of my head. Perhaps it'll help clarify things for readers of this SO. It is woefully inadequate in a manner I'll mention at the end. So don't use it in the docs. But perhaps it'll help inspire a decent analogy for adding to the docs.
A program is like a recipe for a cake. In our analogy it mixes instructions for preparing it and baking it.
Compiling a program is following the instructions for preparing the cake.
Running a program is following the instructions for putting the cake in the oven and baking it.
Precompilation is like preparing a cake and putting it in the fridge to be baked another day.
BEGIN
time is preparation time. If an instruction starts with BEGIN
then that instruction must be followed as soon as it's encountered by someone reading the recipe during preparation of the cake.
Preparation time can be immediately before baking the cake or on a prior day.
Normally the instructions (program) need to work fine whichever strategy is chosen (prepare and immediately bake or prepare, put in fridge, and bake later) by the chef (the compiler and the person using the compiler).
Also, should the use of BEGIN be encouraged (since values computed there are going to be stored in the precompilation cache and thus effectively eliminated from runtime) or discouraged?
Being prepared is generally a good thing. Most of the time, the work to be done for preparing a cake for baking is the same regardless of whether the prepared cake is stored in a fridge for a while or baked immediately after its preparation.
So I'd say encouraged. Certainly not discouraged, at least not in general.
But occasionally it makes sense to defer some work that might be called "preparation" until after the baking has begun. In which case don't use BEGIN
for that because BEGIN
specifically means compile-time in the sense of before run-time, as explained next.
Is there some good use case for this?
A constant is a good candidate for sorting out as part of "preparation".
A constant representing Christmas Day 2018 is a good candidate for defining at compile-time.
A constant representing Christmas Day is probably a good candidate for defining at run-time.
(Corny witticism about baking a Christmas cake intentionally omitted.)
This analogy sucks because as soon as you bake a cake (run a program) the prepared cake (precompilation cache entry) is gone.
The notion of cooking something needs to be replaced with a process that involves preparing (compiling) something that can then be copied any number of times to use it (run it). It'll also need to analogize well in explaining how sometimes "preparation" ought happen at run time.
Extra marks if the analogy has the same oddity that the tool used is called a "fooer" even though it's used to both "foo" ("compile") and "bar" ("run") the thing (program).