Call/1 and '$meta_call'/1 discrepancy

Toying around with some test cases I get:

/* SWI-Prolog 9.3.0 */
?- call((Y=!,(X=1;X=2),Y,X=2)).
Y = !,
X = 2.

?- '$meta_call'((Y=!,(X=1;X=2),Y,X=2)).
false.

Bug or feature? If feature, is it documented? One could
argue, that it is a feature, since one can spare one pass,
since body conversion is ommited.

Edit 06.03.2024
Similar sympthom, different error message:

/* SWI-Prolog 9.3.0 */
?- call(((X=1;X=2),1,X=2)).
ERROR: Type error: `callable' expected, found 
`(_168=1;_168=2),1,_168=2' (a compound)

?- '$meta_call'(((X=1;X=2),1,X=2)).
ERROR: Type error: `callable' expected, found `1' (an integer)

Since used in reset/3, might create reset/3 discrepancy
to Scryer Prolog maybe? Have to check.

I guess that is the inherit difference between interpreting and compiling. call/1 compiles to code that is stored on the stack. That is why we can’t use it for reset/3 as reset stores the state as a list of frames, where each frame holds the (still life) variables of the environment and the clause with the PC. As I think about it, possible we could make this work in reset/3 by saving the code in the reset state …

Note that ECLiPSe, which interprets meta calls also does

[eclipse 1]: call((Y=!,(X=1;X=2),Y,X=2)).

No (0.00s cpu)

I think ISO demands analysis. The other solution would be to first analyze the goal and rewrite variables in goal positions to call(X). That is rather bad for performance though.

SWI-Prolog checks that a meta-call is a control structure. If not, it simply makes the call. If it is, the code is compiled and executed. That is relatively slow, but has the advantage that execution is fast, which is relevant if there is a lot of backtracking during the execution. Think for example about the SPARQL engine that is part of Cliopatria. This compiles SPARQL to a Prolog goal and than calls it. The resulting goal can be huge and its execution typically involves a lot of backtracking. Interpretation has the advantage that it starts immediately and may fail early, so you never have to consider part of the goal. The analysis above combines the worst of both world :frowning: