Should closures allow recursion?

I wasn’t sure where to discuss this.

main :-
	_rel=[X]>>(writeln(X),Y=3,call(_rel,Y)),
	call(_rel,2).
?- main.
2
false.

See above code. In my understanding, FP closures should be able to be bound to variables then called. That’s possible, however, the above code fails. It seems that’s because,

main2 :-
	_rel=[X]>>(writeln(X)),
	X=2,
	call(_rel,Y).
?- main2.
2
true.

Even the arguments are unified with the surrounding environment. This persists, hence on the second call X is already unified with 2, it fails. I believe this is not fully FP behavior.

  1. Is this intended? (Perhaps due to being LP the behaviour should be different, or the main use for lambdas is not this.)
  2. Is it possible to change this with library code?
  3. Should it be like this, etc.

I am afraid that this comment is irrelevant and might be just a noise for your purpose, but I would like to put a comment for just in case that my pack pac allows recursive closures, moreover system of recursive closures. This closures is only personal use out of my curiosity. In fact, I used these recursive closures only to expand regular expressions to DCG via minimal automata, which worked well for that purpose of mine.

In fact, once I proposed this kind of closure to SWI-Prolog forum long time ago but failed to get attentions, because, I think, LAMBDA is so well designed.

This sample query is append/3 in the form of recursive closure and its use:

% ?- let(F, rec(Concat, [[], Y, Y] & ([[A|X], Y, [A|Z]]:-call(Concat, X, Y,Z)))), 
%   listing(F), call(F, A, B, [a,b,c]).

%@ :- dynamic'pac#10'/3.
%@
%@ 'pac#10'([], A, A).
%@ 'pac#10'([A|B], C, [A|D]) :-
%@     'pac#10'(B, C, D).
%@
%@ F = pac:'pac#10',
%@ Concat = 'pac#10',
%@ A = [],
%@ B = [a, b, c] ;
%@ F = pac:'pac#10',
%@ Concat = 'pac#10',
%@ A = [a],
%@ B = [b, c] ;
%@ F = pac:'pac#10',
%@ Concat = 'pac#10',
%@ A = [a, b],
%@ B = [c] ;
%@ F = pac:'pac#10',
%@ Concat = 'pac#10',
%@ A = [a, b, c],
%@ B = [] ;
%@ false.
:- use_module(library(pac)).
?- let(X,pred([X,2])),call(X,_,Y),writeln(Y).

?- let(F, rec(Concat, [[], Y, Y] & ([[A|X], Y, [A|Z]]:-call(Concat, X, Y,Z)))), listing(F), call(F, A, B, [a,b,c]).

This gives me the following error on 8.2.3.

2
ERROR: c:/cygwin64/home/computer/pl/coret2.pl:4:33: Syntax error: Operator expected

how about insert ?- module(pac). before the query. Any way I will check after going back home. Sorry the poorest doc in the planet.

EDIT.

I have checked that inserting “?- module(pac).” works for this case.

?- use_module(library(pac)).
true.

?- module(pac).
true.

pac: ?- let(X,pred([X,2])),call(X,_,Y),writeln(Y).
2
X = pac:'pac#2',
Y = 2.

(snip)

The recursive closure may be put directly as a meta argument of call without let/2

pac: ?- call(rec(Concat, [[], Y, Y] & ([[A|X], Y, [A|Z]]:-call(Concat, X, Y,Z))), A, B, [a,b,c]).

(snip)