1

What is the difference between these two goals?

foo(A) :- A, !, fail.
foo(A).
foo(A) :- call(A), !, fail.
foo(A).

They seem to behave identically? What is the purpose of call/1 and is there an example of when it matters?

kentrid
  • 121
  • 2
  • It could matter if you have modules in your program. I am not sure how GNU-Prolog deals with modules though. As is, your `foo/1` is a meta-predicate. You could maybe read up on meta-predicates in the docs for the Prolog you are using (GNU-Prolog?) and tell us if there is anything interesting. – TA_intern Oct 20 '20 at 06:47
  • OK, I looked it up. GNU-Prolog does not support modules. Other Prologs do. – TA_intern Oct 20 '20 at 06:51

1 Answers1

1

There is no difference in the output WAM code generated by those snippets of code, as evidenced by issuing

gplc -w snippet1.pl
gplc -w snippet2.pl

and checking the generated wbc file (where snippetN.pl contains either sample code). So it seems is a programmer's choice which one to use. It might be useful to use call/1 for portability reasons.

Recall however the existence of call/N with N > 1 which is useful if you want to call a goal which has arguments.

For the curious, this is the generated wam file: predicate(foo/1,1,static,private,monofile,global,2).

clause(:-(foo(A),','(A,','(!,fail))),[
    allocate(1),
    get_variable(y(0),1),
    put_atom(foo,1),
    put_integer(1,2),
    put_atom(true,3),
    call(('$call')/4),
    cut(y(0)),
    fail]).


clause(foo(_),[
    proceed]).

The only difference is in the header for the clause which in the other snippet reads:

clause(:-(foo(A),','(call(A),','(!,fail))),[
gusbro
  • 22,357
  • 35
  • 46
  • Thank you. So in what instance is `call/1` useful? – kentrid Oct 19 '20 at 18:09
  • I never use your first snippet `A`, but `call(A)`. So for me it is useful `call/1` as my choice as a programmer is to use the latter. `call/1` is also part of the ISO standard so any conforming processor would provide it. I don't think that just issuing `A` is ISO standard. I think it is more portable to use `call(A)` rather than just `A`. – gusbro Oct 19 '20 at 18:16
  • Is there an example where `call/1` is useful (not `call/N`)? – kentrid Oct 19 '20 at 18:37
  • Portability is an example I suggested you – gusbro Oct 19 '20 at 18:54
  • This is catch against typo's like using a capital letter in a predicate call in the clause body. Using call/1 makes things unambiguous. – peter.cyc Nov 06 '20 at 21:16
  • @peter.cyc: typos are usually catch by the lint which will issue a singleton variable warning which you should always check – gusbro Nov 08 '20 at 01:33