SWI-Prolog-Education/talespin-annie

Change `ensure_loaded/1` to `use_module/1`

pmoura opened this issue · 5 comments

talespin-annie/run.pl

Lines 15 to 18 in a2652fe

:-ensure_loaded(talespin).
:-ensure_loaded(anglify).
:-ensure_loaded(fairy).
:-ensure_loaded(snail).

It's bad programming style to use ensure_loaded/1 when you meant use_module/1.

I don't want to import into the run space, I meant to use ensure_loaded.
After being burnt by load-on-demand once too often, I usually force loading in a known order. .
in particular, fairy and snail are the actions, and aren't going to be loaded by anyone else, they're referred to without import. That's all controled by 'Genre'.

8cD Thanks - gives me stuff to think about!

Following the instructions on your readme file:

$ swipl run.pl
ERROR: /Users/pmoura/Downloads/talespin-annie-master/run.pl:18:
	import/1: No permission to import snail:action/2 into run (already imported from fairy)

If you comment the two last ensure_loaded/1 directives you avoid the error. Then try:

?- module(run).
true.

run:  ?- predicate_property(story(_,_,_,_), P).
P = interpreted ;
P = visible ;
P = static ;
P = imported_from(talespin) ;
...

I.e. ensure_loaded/1 directives written inside a module do the same as use_module/1 directives. If you don't want to import into the run space, you need to move the ensure_loaded/1 directives outside the module.

But a simple fix is to remove the module/2 directive in the run.pl file and replace the ensure_loaded/1 directives with:

:- use_module(talespin).
:- use_module(anglify).
:- use_module(fairy, []).
:- use_module(snail, []).

This allows the run.pl file to load without import errors.

Aaaah! I was NOT aware that ensure_loaded behaved differently inside a module. That's kind of crazy. I'd misunderstood the origin of that error message.

Thanks!

I didn't remove the module/2 directive, but did change to use_module, and removed all exports from fairy and snail modules. That's the correct solution, since they should never be called without explicit module qualification.

"Fairy" and "Snail" are different genres, different worlds of action. The second arg of story/4 is the genre. Eventually anglify/2 should have an extra argument, or should be anglify_snail, but for now it's hardcoded. Making a genre turns out to be lots of work, and I'll probably not be too interested in starting a new one any time soon!
(fairy is a stub).