`fold/3`, `fold/4`, `fold/5` as members of a family of `foldl/4`

I have introduced meta predicates `fold/3`, `fold/4`, `fold/5`.
Although they are byproduct caused by my big misunderstanding issues on `foreach` discussed on a thread else, these three are what I wanted have since earlier. I borrowed the name `fold` because it is a generalized `foldl/4` for me. They are all small and clear, and prefixed sample queries are enough for the reader, I hope. In fact, I guess the reader already uses similar ones in his private use. I will be glad if they would be shared with others. Also I would like to see such private handy tools of others for their daily use.

EDIT:
Since about 10 years ago I had meta predicates for `repeating` action, though they were always in a messy state, because without that it is easy for us to write simple repeating action in Prolog like

`between(1, 5, I), writeln(I), fail; true `

Remembering the traditional idea of Prolog of â€śbacktracking as a generalized recursion,â€ť now I have changed my mind so that I should cleanup my messy meta predicates for repeating (recursion) in stead of introducing similar predicates.

In addition, to be honest I donâ€™t know the background of the name â€śfoldâ€ť. I think it came from mathematics, but but as far as I know they seem different from repeating action. It may not be appropriate to give name â€śfoldâ€ť to repeating action like the above example.

End of EDIT.

``````% ?- N is 10^8, time(fold(I, between(1, N, I),  is(C, 1+2))).
% ?- fold(M, member(M, [1,2,3]), cons, [], X).
%@ X = [3, 2, 1].
cons(X, Y, [X|Y]).

:- meta_predicate fold(?, :, :, ?, ?).
fold(V, G, A, X, Y):-	Acc = '\$ACC'(X),
(	call(G),
arg(1, Acc, U),
call(A, V, U, W),
nb_setarg(1, Acc, W),
fail
;	arg(1, Acc, Y)
).

% ?- Sum = acc(0), fold(J, between(1, 3, J), test_add_to_acc, Sum).
%@ Sum = acc(6).
V0 is X + V,
nb_setarg(1, Acc, V0).

:- meta_predicate fold(?, :, :, ?).
fold(V, G, A, X):-
call(G),
call(A, V, X),
fail.
fold(_, _, _, _).

% ?- fold(I, between(1, 3, I), writeln).
%@ 1
%@ 2
%@ 3
%@ true.
% ?- fold(I, between(1, 3, I), X^(Y is X*X, writeln(Y))).
%@ 1
%@ 4
%@ 9
%@ I = X.

:- meta_predicate fold(?, :, :).
fold(V, G, V^A):-!,
(	call(G),
call(A),
fail
;	true
).
fold(V, G, A):-
(	call(G),
call(A, V),
fail
;	true
).
``````
1 Like