Adding named static constants

I’m using: SWI-Prolog version 9.0.4

My goal is to create named static constants, at compile time, akin to c #define functionality. By “at compile time”, I mean that the symbols, and their values, are known and in force before application code is compiled.

An alternative problem statement is to provide the ability to load c #define before application code is processed. I’ll just put my static constant definitions into #define format.

Naively, I would think this is about assigning a value to an atom. But is this not a prolog language standard violation? Are not the name of a non-numeric atom and its value

Maybe a symbol table entry is the answer? Is there some way to get things into the symbol table from application code, Does this solve the problem? Are there adverse side effects in doing so?

Can the method used to recognize end_of_file and -1 as synonymous be exploited?

Can the foreign language interface features that processes c #define statements help here?

I understand this is trivial if addressed at run time, say with assert/call, but I want to avoid the need to decode the incoming bytes to get the symbolic request, formulate a symbolic response, and then encode the symbolic response into byte values to send.

Named static constants avoid all this and I expect will have broad use and appeal.

Thank you for your assistance.

Could you please provide a concrete example of what you want?

You can easily store constants, e.g.:

const(pi, 3.141592653589793238).
const(e, 2.718281828459045235).

although in this case, you could get these values as is/2 builtins:

?- X is pi.
X = 3.141592653589793.
?- X is e.
X = 2.718281828459045.

Or, it’s possible that goal_expansion/2 will do what you want.

The ffi pack does something like that for providing access to C #defines from the headers. After fetching the values from the headers it uses term_expansion/2 to go through each clause and replace atoms that match one of the C constants to the value.

I’m not really sure how useful it is. The normal Prolog way is indeed to use facts to define your constants and pick them up at runtime. It is rare that this is performance-wise a problem. If it is, it is fairly easy to use goal_expansion/2 to do the lookup at compile time.

XSB has something that resembles the C preprocessor. SWI-Prolog used to have something like that, but it was barely ever used and eventually was discarded.

1 Like

Doesn’t library(settings) address a similar use-case? Or am I misunderstanding the original question?

No. At least, that is not how it is intended. It is intended to allow an application to make declarations about the application configuration that can be modified, saved and reloaded. This dynamic aspect, including making runtime changes and announcing these as events to allow the application to reflect the changes , makes it different from what @zbpkl wants (if I understand it correctly).

I think I understand now.

In a system which in fact supports runtime changes to the source code (including the amazing hot-fixing and redo!) the distinction between “compile time” and “run time” gets a bit fuzzy. Is there better terminology we can use?

1 Like

Thank you everyone for your helpful input.

I believe goal_expansion solves the problem.