Good question. I’m not a big fan of having to rely on
-g command. It makes the commands long and quoting gets hard, in particular when part of the command comes from variables in the shell script (you rarely want to type this stuff into an interactive shell) and multiple layers of scripts with their own quote rules are involved. So,
-Dflag=value is typically a lot more user friendly. It is also consistent with what several other applications do. Think about (C) compilers, cmake, make (although make uses simply
name=value) and more.
Second is when to apply the flag. Using
-g ... is applied after loading all code ((user) init scripts, command-line Prolog files, etc). That is needed as it is intended to run some goal using the code you just loaded. That is too late for affecting the loading process.
The dedicated commandline arguments are processed “when needed”. We can do the same for the
-D flags that have a well defined meaning (and I think we should). An advantage of the dedicated commandline arguments is that we can easily document them in the usage summary. On the other hand, using flags from the commandline we get more control and we only have to document the flags rather than the commandline options and the flags.
Another issue is that undefined commandline options lead to an error. Undefined flags (currently) just create the flag as an r/w flag where the type is derived from the value. I’m unsure whether or not that is a good idea. Note that, unlike ISO, SWI-Prolog allows adding flags at runtime. I think that is good as it allows libraries to add flags (as our apply_macros library now does). In the ISO case each library has to invent its own way to manage settings, deal with the interaction with threads, etc.
Maybe we should be more helpful. One could be to only allow setting new flags using a notation
This may be ambiguous, so possibly this?
But, we don’t always know when the flag is defined. Using
-D on a flag that is introduced in a library that is loaded later is fine IMO.
Another trick to inform the user could be to copy cmake’s behavior and warn if a flag is set, but never queried. So, you get
swipl -Dmyflag=42 ...
WARNING: user flag "myflag" was set but never used.
That should be fairly easy to implement. Both the code using current_prolog_flag/2 on this flag would silence this message as well as a call to create_prolog_flag/3 on this flag.
Slightly related to this is that the typing of flags is weak. Currently, the options are boolean, integer, float, atom or term. Notably atom should probably allow to enumerate the set of admissible atoms. Numbers might have a range.