## Higher order programming: apply/3 implemented in swi

### Higher order programming: apply/3 implemented in swi

The apply/3 predicate is crucial for higher order programming in
prolog.

Maybe I'm just reinventing the wheel, but I haven't found apply/3 in
the manual, or on other prolog sites. And as I saw on this group's
archives, there were some unresolved thread relating to it.
I wrote it, as it was specified here:

http://www.yqcomputer.com/ ~lee/papers/ho/

I copy my code here:

%apply(f(a,b),[c,d,e],f(a,b,c,d,e))
apply(F,A,FA):-
functor(F,Atom,Argc),
countlist(Argc,Argindexes),reverse(Argindexes,Argindexes1),
findall(X,(member(Y,Argindexes1),arg(Y,F,X)),Y),
append(Y,A,YA),
length(YA,Argc1),
functor(FA,Atom,Argc1),
dressup(Argc1,FA,YA).

dressup(0,_,_):-!.
dressup(Index,Expr,ParamList):-
elementat(Index,ParamList,Param),arg(Index,Expr,Param),
I1 is Index-1,dressup(I1,Expr,ParamList).

% countlist(?C,?L)
%L contains numbers from C to 1
countlist(0,[]):-!.
countlist(C,[C|T]):-
C1 is C-1, countlist(C1,T).

elementat(1,[H|_],H):-!.
elementat(C,[_|T],R):- C1 is C-1, elementat(C1,T,R).

### Higher order programming: apply/3 implemented in swi

Is it? In many cases it can be replaced by call/2... That is
what is used in maplist/2.., etc.

It has apply/2 which, I think, is the same as

apply(F, Args) :-
apply(F, Args, Goal),
call(Goal).

In practice however, the length of Args is almost always known at
compiletime, and thus we can use call/2... and avoid the need to
build a list, count its elements, etc.

apply(F,Args,Term) :-
F =.. List,
append(List, Args, All),
Term =.. All.

Cheers --- Jan

### Higher order programming: apply/3 implemented in swi

When using the lambda notation in functional languages, we can create
semi substituted functions. In prolog its equivalent is a predicate
with incorrect arity. Calling it will give us errors. apply/2 calls it
prematurely, that's the problem.

### Higher order programming: apply/3 implemented in swi

<snip>

That is an answer on why you sometimes need apply/3 (true, sometimes you
wish to extend the arguments without making the call; for example DCG
translation does this).

Still, I don't see where your code is different in functionality from
the trivial code above. Ok, my code creates two intermediate lists that
can be avoided at the cost of a bit more programming, but your code
creates even more intermediate datastructures.

--- Jan

### Higher order programming: apply/3 implemented in swi

"

apply(F,Args,Term) :-
F =.. List,
append(List, Args, All),
Term =.. All.

"
I've just noticed this part of your message: yeah, you're right, it's
more elegant. I wasn't aware of the use of " ..: operator. Thanks for
pointing out.

### Higher order programming: apply/3 implemented in swi

>> apply(F,Args,Term) :-

I read a bit superficial. I've just noticed this part of your message.
Yes, your code is more elegant, I just wasn't aware of the operator
"..". Thanks for pointing out.