Compile-time code vs. Runtime code

A Prolog program has up to three types of code in it:

  1. code that implements the application;
  2. code that helps compile the application, and that is not used during the execution of the application;
  3. code that is necessary to both the execution of the application and its compilation.
The first type of code is the normal case and may be referred to as runtime code, since it is intended to be executed when the application is run. The second type of code is called compile-time code. Any predicates that are to be called from embedded commands are examples of compile-time code. The other main use of compile-time code is in the definition of term_expansion/2, which allows you to specify arbitrary transformations to be done by the compiler as it reads in clauses. See the reference page for more information on term_expansion/2.

When using the built-in compiler in the Development System, no distinction has to be made between the three types of code. They can coexist in one file. Before using qpc on a program, however, compile-time code must be separated out into its own file (or files). Then, to each file that needs this new file or files at compile time, add the goal (A) near the top of the file. This tells qpc to load NewFile directly into qpc before further compiling the current file. It does not include NewFile as a runtime dependency of the file. If you need NewFile to be loaded at compile time and also at runtime, use the goal (B) instead. This approach will work in the Development System as well as qpc.

     :- load_files(NewFile, [when(compile_time)]).   (A)
     :- load_files(NewFile, [when(both)]).           (B)

Alternatively, you may omit the use of load_files/2, instead specifying files to be loaded into qpc with the -i option. In this case, when you want to compile this file into the Development System, remember to first load the file(s) needed at compile time.

It is good programming style to use initialization/1 for goals to be activated at runtime. Note that predicates called as :- Goal. need to be available at compile time, whereas predicates called as :- initialization(Goal). only need to be available at runtime.