PROLOG with lambda expressions
Lean Prolog is implemented in Java and can run Logtalk, which makes lambda expressions available to to all supported backend Prolog compilers. For an overview of Logtalk's lambda expressions syntax see e.g.:
https://logtalk.org/2009/12/08/lambda-expressions-in-logtalk.html/
For usage examples see:
https://github.com/LogtalkDotOrg/logtalk3/tree/master/examples/lambdas
There is an Prolog lambda implementation by Ulrich Neumerkel. SWI-Prolog for example supports it. If you did a search in Stackoverflow:
[swi-prolog] lambda
you can also find quite a few answers using it for solutions.
Also, the web-page that explains it all
There are basically two approaches around for lambda expressions in Prolog, that only address the invocation of lambda expressions and not higher order unification:
global-by-default: The variables in the body of the lambda expression are global by default, if they are not mentioned by an extra binder.
local-by-default: The variables in the body of the lambda expression are local by default, if they are not mentioned by an extra binder.
Representatives of local-by-default are for example Ulrich Neumerkel's library(lambda) or the lambda expressions found in Logtalk. The global-by-default approach is currently followed by the lambda expressions found in Jekejeke Prolog.
Both approaches allow to model the same mathematical lambda expressions and solve the following problems by some further syntax:
Control of sharing or non-sharing of variables across multiple invocations.
Forcing of alpha conversion for binders and local variables in the body of the lambda expression.
Here is an example, factorial via the Y combinator:
- global-by-default: Jekejeke Prolog API Source
?- Y = F\X^call(X\call(F,call(X,X)),X\call(F,call(X,X))), Fact = F\J^H^M^N^N\J^H^M^M\J^H^(N=0,M=1;N>0,H is N-1,call(F,H,J),M is N*J), call(Y,Fact,10,R). R = 3628800.
- local-by-default: Ulrich Neumerkel's library(lambda)
?- Y = \F^call([F]+\X^call(F,call(X,X)),[F]+\X^call(F,call(X,X))), Fact = \F^([F]+\N^([N,F]+\M^(N=0,M=1;N>0,H is N-1,call(F,H,J),M is N*J))), call(Y,Fact,10,R). R = 3628800.
Bye
P.S.: The distinction global-by-default and local-by-default is borrowed
from, page 10:
The Language Features and Architecture of B-Prolog
Neng-Fa Zhou, Theory and Practice of Logic Programming, 2011
http://www.sci.brooklyn.cuny.edu/~zhou/papers/tplp11sips.pdf