I want the code to import some_predicate without running it’s initialization predicate.
To reproduce: swipl script1.pl
It runs hello world 2! and there seems no way to ignore the initialization of script2. Is it possible to ignore the main predicate of the other file? Of course, there are workarounds, but it would be nice to be able to import predicates from a script that has a main predicate.
$ swipl script1.pl
Warning: /Users/pmoura/Downloads/swi_initialization_bug-master/script1.pl:7:
Warning: Redefined static procedure main/0
Warning: Previously defined at /Users/pmoura/Downloads/swi_initialization_bug-master/script2.pl:6
WEWHello world!
To be safe, you would likely want to delete the clause for term_expansion/2 above after loading the script2.pl file.
P.S. Logtalk term-expansion mechanism provide a clean solution here as it allows loading a file while specifying the hook object (or hook module) used to expand it, without having the expansion rules affecting anything else.
I don’t think this is a very odd setup. It’s pretty normal to have two prolog files that could be run as scripts separately but still contain some predicates that you want to use as well.
In that case, maybe instead move those predicates to a separate file and then bring them to the scripts using the include/1 directive? That would be a better solution.
That depends if by “possible in SWI-Prolog” means just what’s part of its distribution or includes third-party solutions that run on it. I still think that an include/1 based solution is the simplest and cleanest solution. The Logtalk solution I hinted about is also clean but overkill here:
There is. See initialization/2 rather than ISO initialization/1. Notably, initialization(Goal, main) defines the entry point of your program. There is only one such thing (see docs for which one wins if there are more). Most importantly,
the entry point is executed on swipl script.pl, but not on swipl -l script.pl or loading the file in swipl using ?- [script].
This has been added relatively recently, not sure it is in the stable or you need the devel versions.
edit Before the initialization(Goal,main) alternative I tended to have a load.pl that loads the application and a run.pl that loads load.pl and calls the entry point.
For debugging, I use swipl -g my_program:main -l my_program.pl -- args. This also plays nicely with make/0. (my_program.pl has the directive :-initialization(main,main)..
When not debugging, I compile the program and use my_program.qlf args.
I never liked SWI’s (Jan’s) choice of main/0 as the default entry point.
pack(upsh) looks first for /1,0 of script .pl .
This leads to far fewer classes.
On the other hand, I don’t like what you are trying to do either.
If you have code that is needed by more than one scripts, then put the common bits somewhere else.
Packs are really good places for such things.
There is nothing to stop you from having private ones.
One limitation of SWI is that uses monolithic packs. And that discourages
catch-all/ medley packs.
Pack(lib) can be used to provide on-demand loading of bits of packs.
For example see pack(stoics_lib).
Where you can load into script1.pl only the bits you need with something like
:- lib(stoics_lib:en_list/2).