swipl-devel icon indicating copy to clipboard operation
swipl-devel copied to clipboard

SICStus emulation: goal expansion for explicit module prefixes no longer working

Open dgelessus opened this issue 3 years ago • 0 comments

The SICStus emulation defines a goal expansion for emulating library predicate calls with explicit module prefixes, so that e. g. lists:nth(1, List, E) is rewritten to call the emulated predicate sicstus_lists:nth, instead of trying to call a non-existant nth predicate in the real SWI lists module.

It seems that currently this doesn't work at all. For example, with the following code, the goal expansion doesn't take effect:

:- module(test, [foo/3]).
:- expects_dialect(sicstus).
:- use_module(library(lists)).
foo(Index, List, Element) :- lists:nth(Index, List, Element).

Calling foo gives an error about lists:nth not existing, even though the goal expansion should have rewritten it to sicstus_lists:nth (which does exist). trace(system:goal_expansion/2) shows that goal_expansion is called, but the goal that is passed in has the module prefix removed. The implementation in library/dialect/sicstus.pl expects to receive a module prefix, so it will always fail.

Looking though the history, this might have been broken by a2fb4f640b338caf87473bdc0e52e9d0648d4d59 in 2016, which makes the expand_goal internals always remove module prefixes. Before this change, it would first attempt to call goal_expansion with the module prefix included in the goal, and only if that failed it would remove the module prefix. (The goal expansion in the SICStus emulation was added in 2010, so it seems logical that it might have relied on the old behavior.)

I'm not sure what would be a good way to fix this. Using term_expansion instead of goal_expansion would probably work, but that would require reimplementing most of the internal goal_expansion logic.

This isn't a big issue for me - I've used the SICStus emulation for almost half a year and only now noticed that this part isn't working. It's also easy to work around in my case - the problematic call in our code doesn't need a module prefix, and everything works as expected if I remove the module prefix.

dgelessus avatar May 19 '21 19:05 dgelessus