I see that swi prolog is landing a closure package. That's good. This led to me dusting off my closure implementation in guile-log which had bit-rotten somewhat and needed a retake. This is now the interface.

A closure can be created simplest with `name{X,...Z|Goal}`

or for non arguments, `name{|Goal}`

it will be directly inserted into the forms meaning that you can't currently manage these lambdas as code objects en e.g. macros. So an example would be

```
prolog> X is lam{X|X is 1},X(A).
--->
X = lam
A = 1
```

Note that we name the closure creation function `lam`

and enter it in the name space which means that now this will be equivalent,

```
prolog> X is lam(), X(A).
--->
X = lam
A = 1
```

This is useful, but you might not want to name it in that case use `lambda`

or `λ`

and then a unique name will be generated. Anyway naming the lambdas can lead to interesting applications as a way to create closures generating functions. A problem in prolog is to close variables over, we depart here from swi prolog implementation in that closed over variables is marked like `v[X]`

. This means that we can now design more useful lambdas. Here is a show case

```
prolog> var(Y),G is lam{X|X is v[Y]},Y is 1,G(A),set(Y,2),G(B).
–>
G = lam,
Y = 2.
A = 1,
B = 2.
```

Note here that all variables in `is,<,>,...`

is has an implicit lookup which is why this works. If you used `X = Y`

in stead we would get `A=2`

in stead.

A closure can create closures which can create closures. This works

```
prolog> var(Y),F=lam{S,G|S is s{X|set(v[Y],X)},
G is g{X|X is v[Y] }},
F(S,G),S(1),G(A),S(2),G(B).
–>
F = lam
S = s
G = g
A = 1
B = 2
Y = 2
```

Now if anywhere in the chain of closures a `Y`

is bound that will take precedence and therefore we could have introduced `Y`

in the first closure like,

```
prolog> F=lam{S,G|var(Y),S is s{X|set(v[Y],X)},
G is g{X|X is v[Y] }},
F(S,G),S(1),G(A),S(2),G(B).
–>
F = lam
S = s
G = g
A = 1
B = 2
```

Note also that we can use the named closure creators and the below is now equivalent

```
prolog> S is s(Y), G is g(Y),S(1),G(A),S(2),G(B).
–>
S = s,
G = g,
A = 1,
B = 2,
Y = 2.
```

Another thing that departs from swi prologs closures is that we have another form that is quite general and we call it a letrec form. the prototype is `lam{LHS1 :- RHS1. ... LHS10 :- RHS10.}`

the predicate shoosen as a closure is also named `lam`

or in case we use annynomous prefix the last predicate inside the bracket. So with this we can do

```
prolog> Y=1,X is lam{
f(X) :- X = v[Y].
lam([]).
lam([X|L]) :-
f(X),
lam(L).},
length(A,3),X(A).
–>
Y = 1
X = lam
A = [1,1,1]
```

Which get's a little more interesting when we can do this after evaluating the above,

```
prolog> X is lam(1), Y is lam(2), Z is lam(_), Y=Z,
length(A,3),X(A),
length(B,3),Y(B),
length(C,3),Z(C).
–>
X = lam,
Y = lam,
Z = lam,
A = [1,1,1],
B = [2,2,2],
C = [2,2,2].
```

Note how we unified two closures. to se more output of the lambdas, please write the term with `quoted(true)`

.

```
prolog> Y=1,X is {X|X is Y},write_term(X,[quoted(true)]),nl.
"A1=lam(1)"
X = lam,
Y = 1.
```

Happy hacking!!

## Comments

comments powered by Disqus